Update Doxygen docs for sequence_diagram namespace
This commit is contained in:
@@ -1,4 +1,15 @@
|
|||||||
# Test cases index
|
# Test cases index
|
||||||
|
|
||||||
|
<!-- toc -->
|
||||||
|
|
||||||
|
* [Class diagrams](#class-diagrams)
|
||||||
|
* [Sequence diagrams](#sequence-diagrams)
|
||||||
|
* [Package diagrams](#package-diagrams)
|
||||||
|
* [Include diagrams](#include-diagrams)
|
||||||
|
* [Other diagrams](#other-diagrams)
|
||||||
|
|
||||||
|
<!-- tocstop -->
|
||||||
|
|
||||||
## Class diagrams
|
## Class diagrams
|
||||||
* [t00002](./test_cases/t00002.md) - Basic class inheritance
|
* [t00002](./test_cases/t00002.md) - Basic class inheritance
|
||||||
* [t00003](./test_cases/t00003.md) - Class fields and methods
|
* [t00003](./test_cases/t00003.md) - Class fields and methods
|
||||||
@@ -112,5 +123,5 @@
|
|||||||
* [t40001](./test_cases/t40001.md) - Basic include graph diagram test case
|
* [t40001](./test_cases/t40001.md) - Basic include graph diagram test case
|
||||||
* [t40002](./test_cases/t40002.md) - Cyclic include graph diagram test case
|
* [t40002](./test_cases/t40002.md) - Cyclic include graph diagram test case
|
||||||
* [t40003](./test_cases/t40003.md) - Dependants and dependencies include diagram filter test
|
* [t40003](./test_cases/t40003.md) - Dependants and dependencies include diagram filter test
|
||||||
## Configuration diagrams
|
## Other diagrams
|
||||||
* [t90000](./test_cases/t90000.md) - Basic config test
|
* [t90000](./test_cases/t90000.md) - Basic config test
|
||||||
|
|||||||
@@ -242,6 +242,13 @@ void generator::generate_activity(const activity &a,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nlohmann::json &generator::current_block_statement() const
|
||||||
|
{
|
||||||
|
assert(!block_statements_stack_.empty());
|
||||||
|
|
||||||
|
return block_statements_stack_.back().get();
|
||||||
|
}
|
||||||
|
|
||||||
void generator::process_call_message(const model::message &m,
|
void generator::process_call_message(const model::message &m,
|
||||||
std::vector<common::model::diagram_element::id_t> &visited) const
|
std::vector<common::model::diagram_element::id_t> &visited) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -40,54 +40,199 @@ using diagram_model = clanguml::sequence_diagram::model::diagram;
|
|||||||
template <typename C, typename D>
|
template <typename C, typename D>
|
||||||
using common_generator = clanguml::common::generators::json::generator<C, D>;
|
using common_generator = clanguml::common::generators::json::generator<C, D>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sequence diagram JSON generator
|
||||||
|
*/
|
||||||
class generator : public common_generator<diagram_config, diagram_model> {
|
class generator : public common_generator<diagram_config, diagram_model> {
|
||||||
public:
|
public:
|
||||||
generator(diagram_config &config, diagram_model &model);
|
generator(diagram_config &config, diagram_model &model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main generator method.
|
||||||
|
*
|
||||||
|
* This method is called first and coordinates the entire diagram
|
||||||
|
* generation.
|
||||||
|
*
|
||||||
|
* @param ostr Output stream.
|
||||||
|
*/
|
||||||
|
void generate(std::ostream &ostr) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate sequence diagram message.
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
* @param parent JSON node
|
||||||
|
*/
|
||||||
void generate_call(const sequence_diagram::model::message &m,
|
void generate_call(const sequence_diagram::model::message &m,
|
||||||
nlohmann::json &parent) const;
|
nlohmann::json &parent) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate sequence diagram participant
|
||||||
|
*
|
||||||
|
* @param parent JSON node
|
||||||
|
* @param id Participant id
|
||||||
|
* @param force If true, generate the participant even if its not in
|
||||||
|
* the set of active participants
|
||||||
|
* @return Id of the generated participant
|
||||||
|
*/
|
||||||
common::id_t generate_participant(
|
common::id_t generate_participant(
|
||||||
nlohmann::json &parent, common::id_t id, bool force = false) const;
|
nlohmann::json &parent, common::id_t id, bool force = false) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate sequence diagram participant by name
|
||||||
|
*
|
||||||
|
* This is convienience wrapper over `generate_participant()` by id.
|
||||||
|
*
|
||||||
|
* @param parent JSON node
|
||||||
|
* @param name Full participant name
|
||||||
|
*/
|
||||||
void generate_participant(
|
void generate_participant(
|
||||||
nlohmann::json &parent, const std::string &name) const;
|
nlohmann::json &parent, const std::string &name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate sequence diagram activity.
|
||||||
|
*
|
||||||
|
* @param a Activity model
|
||||||
|
* @param visited List of already visited participants, this is necessary
|
||||||
|
* for breaking infinite recursion on recursive calls
|
||||||
|
*/
|
||||||
void generate_activity(const sequence_diagram::model::activity &a,
|
void generate_activity(const sequence_diagram::model::activity &a,
|
||||||
std::vector<common::model::diagram_element::id_t> &visited) const;
|
std::vector<common::model::diagram_element::id_t> &visited) const;
|
||||||
|
|
||||||
void generate(std::ostream &ostr) const override;
|
/**
|
||||||
|
* @brief Get reference to the current block statement.
|
||||||
nlohmann::json ¤t_block_statement() const
|
*
|
||||||
{
|
* This method returns a reference to the last block statement (e.g if
|
||||||
assert(!block_statements_stack_.empty());
|
* statement or for loop) in the call stack.
|
||||||
|
*
|
||||||
return block_statements_stack_.back().get();
|
* @return Reference to the current block statement.
|
||||||
}
|
*/
|
||||||
|
nlohmann::json ¤t_block_statement() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Check if specified participant has already been generated.
|
||||||
|
*
|
||||||
|
* @param id Participant id.
|
||||||
|
* @return True, if participant has already been generated.
|
||||||
|
*/
|
||||||
bool is_participant_generated(common::id_t id) const;
|
bool is_participant_generated(common::id_t id) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process call message
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
* @param visited List of already visited participants
|
||||||
|
*/
|
||||||
void process_call_message(const model::message &m,
|
void process_call_message(const model::message &m,
|
||||||
std::vector<common::model::diagram_element::id_t> &visited) const;
|
std::vector<common::model::diagram_element::id_t> &visited) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `if` statement message
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
void process_if_message(const model::message &m) const;
|
void process_if_message(const model::message &m) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `else if` statement message
|
||||||
|
*/
|
||||||
void process_else_if_message() const;
|
void process_else_if_message() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `end if` statement message
|
||||||
|
*/
|
||||||
void process_end_if_message() const;
|
void process_end_if_message() const;
|
||||||
void process_end_conditional_message() const;
|
|
||||||
void process_conditional_else_message() const;
|
/**
|
||||||
|
* @brief Process `:?` statement message
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
void process_conditional_message(const model::message &m) const;
|
void process_conditional_message(const model::message &m) const;
|
||||||
void process_end_switch_message() const;
|
|
||||||
void process_case_message(const model::message &m) const;
|
/**
|
||||||
|
* @brief Process end of conditional statement message
|
||||||
|
*/
|
||||||
|
void process_end_conditional_message() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process conditional else statement message
|
||||||
|
*/
|
||||||
|
void process_conditional_else_message() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `switch` statement message
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
void process_switch_message(const model::message &m) const;
|
void process_switch_message(const model::message &m) const;
|
||||||
void process_end_try_message() const;
|
|
||||||
void process_catch_message() const;
|
/**
|
||||||
|
* @brief Process switch end statement message
|
||||||
|
*/
|
||||||
|
void process_end_switch_message() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `switch` `case` statement message
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
|
void process_case_message(const model::message &m) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `try` statement message
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
void process_try_message(const model::message &m) const;
|
void process_try_message(const model::message &m) const;
|
||||||
void process_end_do_message() const;
|
|
||||||
|
/**
|
||||||
|
* @brief Process `try` end statement message
|
||||||
|
*/
|
||||||
|
void process_end_try_message() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `catch` statement message
|
||||||
|
*/
|
||||||
|
void process_catch_message() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `do` loop statement message
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
void process_do_message(const model::message &m) const;
|
void process_do_message(const model::message &m) const;
|
||||||
void process_end_for_message() const;
|
|
||||||
|
/**
|
||||||
|
* @brief Process `do` end statement message
|
||||||
|
*/
|
||||||
|
void process_end_do_message() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `for` loop statement message
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
void process_for_message(const model::message &m) const;
|
void process_for_message(const model::message &m) const;
|
||||||
void process_end_while_message() const;
|
|
||||||
|
/**
|
||||||
|
* @brief Process `for` end statement message
|
||||||
|
*/
|
||||||
|
void process_end_for_message() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `while` loop message
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
void process_while_message(const model::message &m) const;
|
void process_while_message(const model::message &m) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process `while` end loop message
|
||||||
|
*/
|
||||||
|
void process_end_while_message() const;
|
||||||
|
|
||||||
mutable std::set<common::id_t> generated_participants_;
|
mutable std::set<common::id_t> generated_participants_;
|
||||||
|
|
||||||
mutable nlohmann::json json_;
|
mutable nlohmann::json json_;
|
||||||
|
|||||||
@@ -42,35 +42,102 @@ template <typename C, typename D>
|
|||||||
using common_generator =
|
using common_generator =
|
||||||
clanguml::common::generators::plantuml::generator<C, D>;
|
clanguml::common::generators::plantuml::generator<C, D>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sequence diagram PlantUML generator
|
||||||
|
*/
|
||||||
class generator : public common_generator<diagram_config, diagram_model> {
|
class generator : public common_generator<diagram_config, diagram_model> {
|
||||||
public:
|
public:
|
||||||
generator(diagram_config &config, diagram_model &model);
|
generator(diagram_config &config, diagram_model &model);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main generator method.
|
||||||
|
*
|
||||||
|
* This method is called first and coordinates the entire diagram
|
||||||
|
* generation.
|
||||||
|
*
|
||||||
|
* @param ostr Output stream.
|
||||||
|
*/
|
||||||
|
void generate(std::ostream &ostr) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate sequence diagram message.
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
* @param ostr Output stream
|
||||||
|
*/
|
||||||
void generate_call(const clanguml::sequence_diagram::model::message &m,
|
void generate_call(const clanguml::sequence_diagram::model::message &m,
|
||||||
std::ostream &ostr) const;
|
std::ostream &ostr) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate sequence diagram return message
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
* @param ostr Output stream
|
||||||
|
*/
|
||||||
void generate_return(const clanguml::sequence_diagram::model::message &m,
|
void generate_return(const clanguml::sequence_diagram::model::message &m,
|
||||||
std::ostream &ostr) const;
|
std::ostream &ostr) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate sequence diagram participant
|
||||||
|
*
|
||||||
|
* @param ostr Output stream
|
||||||
|
* @param id Participant id
|
||||||
|
* @param force If true, generate the participant even if its not in
|
||||||
|
* the set of active participants
|
||||||
|
* @return Id of the generated participant
|
||||||
|
*/
|
||||||
void generate_participant(
|
void generate_participant(
|
||||||
std::ostream &ostr, common::id_t id, bool force = false) const;
|
std::ostream &ostr, common::id_t id, bool force = false) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate sequence diagram participant by name
|
||||||
|
*
|
||||||
|
* This is convienience wrapper over `generate_participant()` by id.
|
||||||
|
*
|
||||||
|
* @param ostr Output stream
|
||||||
|
* @param name Full participant name
|
||||||
|
*/
|
||||||
void generate_participant(
|
void generate_participant(
|
||||||
std::ostream &ostr, const std::string &name) const;
|
std::ostream &ostr, const std::string &name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate sequence diagram activity.
|
||||||
|
*
|
||||||
|
* @param a Activity model
|
||||||
|
* @param ostr Output stream
|
||||||
|
* @param visited List of already visited participants, this is necessary
|
||||||
|
* for breaking infinite recursion on recursive calls
|
||||||
|
*/
|
||||||
void generate_activity(const clanguml::sequence_diagram::model::activity &a,
|
void generate_activity(const clanguml::sequence_diagram::model::activity &a,
|
||||||
std::ostream &ostr,
|
std::ostream &ostr,
|
||||||
std::vector<common::model::diagram_element::id_t> &visited) const;
|
std::vector<common::model::diagram_element::id_t> &visited) const;
|
||||||
|
|
||||||
void generate(std::ostream &ostr) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Check if specified participant has already been generated.
|
||||||
|
*
|
||||||
|
* @param id Participant id.
|
||||||
|
* @return True, if participant has already been generated.
|
||||||
|
*/
|
||||||
bool is_participant_generated(common::id_t id) const;
|
bool is_participant_generated(common::id_t id) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Generate PlantUML alias for participant
|
||||||
|
*
|
||||||
|
* @param participant Sequence diagram participant model
|
||||||
|
* @return Particpant alias
|
||||||
|
*/
|
||||||
|
std::string generate_alias(const model::participant &participant) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Escape the symbols in the name for PlantUML
|
||||||
|
*
|
||||||
|
* @param name Full participant name
|
||||||
|
* @return Escaped name
|
||||||
|
*/
|
||||||
std::string render_name(std::string name) const;
|
std::string render_name(std::string name) const;
|
||||||
|
|
||||||
mutable std::set<common::id_t> generated_participants_;
|
mutable std::set<common::id_t> generated_participants_;
|
||||||
std::string generate_alias(const model::participant &participant) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace plantuml
|
} // namespace plantuml
|
||||||
|
|||||||
@@ -31,8 +31,6 @@ std::vector<message> &activity::messages() { return messages_; }
|
|||||||
|
|
||||||
const std::vector<message> &activity::messages() const { return messages_; }
|
const std::vector<message> &activity::messages() const { return messages_; }
|
||||||
|
|
||||||
void activity::set_from(common::model::diagram_element::id_t f) { from_ = f; }
|
|
||||||
|
|
||||||
common::model::diagram_element::id_t activity::from() const { return from_; }
|
common::model::diagram_element::id_t activity::from() const { return from_; }
|
||||||
|
|
||||||
} // namespace clanguml::sequence_diagram::model
|
} // namespace clanguml::sequence_diagram::model
|
||||||
|
|||||||
@@ -25,18 +25,44 @@
|
|||||||
|
|
||||||
namespace clanguml::sequence_diagram::model {
|
namespace clanguml::sequence_diagram::model {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Model of a sequence diagram activity
|
||||||
|
*/
|
||||||
class activity {
|
class activity {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* @param id Id of the participant parent for the activity
|
||||||
|
*/
|
||||||
activity(common::model::diagram_element::id_t id);
|
activity(common::model::diagram_element::id_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a message call to the activity
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
void add_message(message m);
|
void add_message(message m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get list of messages in the activity
|
||||||
|
*
|
||||||
|
* @return Reference to list of messages in the activity
|
||||||
|
*/
|
||||||
std::vector<message> &messages();
|
std::vector<message> &messages();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get list of messages in the activity
|
||||||
|
*
|
||||||
|
* @return Reference to list of messages in the activity
|
||||||
|
*/
|
||||||
const std::vector<message> &messages() const;
|
const std::vector<message> &messages() const;
|
||||||
|
|
||||||
void set_from(common::model::diagram_element::id_t f);
|
/**
|
||||||
|
* @brief Get the id of activity parent participant
|
||||||
|
*
|
||||||
|
* @return Id of activity participant
|
||||||
|
*/
|
||||||
common::model::diagram_element::id_t from() const;
|
common::model::diagram_element::id_t from() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -142,10 +142,6 @@ void diagram::add_case_stmt_message(model::message &&m)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool diagram::started() const { return started_; }
|
|
||||||
|
|
||||||
void diagram::started(bool s) { started_ = s; }
|
|
||||||
|
|
||||||
std::map<common::model::diagram_element::id_t, activity> &diagram::sequences()
|
std::map<common::model::diagram_element::id_t, activity> &diagram::sequences()
|
||||||
{
|
{
|
||||||
return sequences_;
|
return sequences_;
|
||||||
@@ -175,12 +171,6 @@ std::set<common::model::diagram_element::id_t> &diagram::active_participants()
|
|||||||
return active_participants_;
|
return active_participants_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::set<common::model::diagram_element::id_t> &
|
|
||||||
diagram::active_participants() const
|
|
||||||
{
|
|
||||||
return active_participants_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void diagram::print() const
|
void diagram::print() const
|
||||||
{
|
{
|
||||||
LOG_TRACE(" --- Participants ---");
|
LOG_TRACE(" --- Participants ---");
|
||||||
|
|||||||
@@ -27,6 +27,11 @@
|
|||||||
|
|
||||||
namespace clanguml::sequence_diagram::model {
|
namespace clanguml::sequence_diagram::model {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Model of a sequence diagram
|
||||||
|
*
|
||||||
|
* @embed{sequence_model_class.svg}
|
||||||
|
*/
|
||||||
class diagram : public clanguml::common::model::diagram {
|
class diagram : public clanguml::common::model::diagram {
|
||||||
public:
|
public:
|
||||||
diagram() = default;
|
diagram() = default;
|
||||||
@@ -36,20 +41,37 @@ public:
|
|||||||
diagram &operator=(const diagram &) = delete;
|
diagram &operator=(const diagram &) = delete;
|
||||||
diagram &operator=(diagram &&) = default;
|
diagram &operator=(diagram &&) = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the diagram model type - in this case sequence.
|
||||||
|
*
|
||||||
|
* @return Type of sequence diagram.
|
||||||
|
*/
|
||||||
common::model::diagram_t type() const override;
|
common::model::diagram_t type() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Search for element in the diagram by fully qualified name.
|
||||||
|
*
|
||||||
|
* @param full_name Fully qualified element name.
|
||||||
|
* @return Optional reference to a diagram element.
|
||||||
|
*/
|
||||||
common::optional_ref<common::model::diagram_element> get(
|
common::optional_ref<common::model::diagram_element> get(
|
||||||
const std::string &full_name) const override;
|
const std::string &full_name) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Search for element in the diagram by id.
|
||||||
|
*
|
||||||
|
* @param id Element id.
|
||||||
|
* @return Optional reference to a diagram element.
|
||||||
|
*/
|
||||||
common::optional_ref<common::model::diagram_element> get(
|
common::optional_ref<common::model::diagram_element> get(
|
||||||
common::model::diagram_element::id_t id) const override;
|
common::model::diagram_element::id_t id) const override;
|
||||||
|
|
||||||
std::string to_alias(const std::string &full_name) const;
|
/**
|
||||||
|
* @brief Get participant by id
|
||||||
inja::json context() const override;
|
*
|
||||||
|
* @param id Participant id.
|
||||||
void print() const;
|
* @return Optional reference to a diagram element.
|
||||||
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
common::optional_ref<T> get_participant(
|
common::optional_ref<T> get_participant(
|
||||||
common::model::diagram_element::id_t id)
|
common::model::diagram_element::id_t id)
|
||||||
@@ -62,52 +84,123 @@ public:
|
|||||||
static_cast<T *>(participants_.at(id).get()));
|
static_cast<T *>(participants_.at(id).get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
/**
|
||||||
common::optional_ref<T> get_participant(
|
* @brief Add sequence diagram participant
|
||||||
common::model::diagram_element::id_t id) const
|
*
|
||||||
{
|
* @param p Sequence diagram participant model
|
||||||
if (participants_.find(id) == participants_.end()) {
|
*/
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
return common::optional_ref<T>(
|
|
||||||
static_cast<T *>(participants_.at(id).get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_participant(std::unique_ptr<participant> p);
|
void add_participant(std::unique_ptr<participant> p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set participant with `id` as active
|
||||||
|
*
|
||||||
|
* @param id Id of participant to activate
|
||||||
|
*/
|
||||||
void add_active_participant(common::model::diagram_element::id_t id);
|
void add_active_participant(common::model::diagram_element::id_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get reference to current activity of a participant
|
||||||
|
*
|
||||||
|
* @param id Participant id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
activity &get_activity(common::model::diagram_element::id_t id);
|
activity &get_activity(common::model::diagram_element::id_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add message to current activity
|
||||||
|
*
|
||||||
|
* @param message Message model
|
||||||
|
*/
|
||||||
void add_message(model::message &&message);
|
void add_message(model::message &&message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add block message to the current activity
|
||||||
|
*
|
||||||
|
* Block messages represent sequence diagram blocks such as `alt`
|
||||||
|
* or `loop`.
|
||||||
|
*
|
||||||
|
* The block messages can be stacked.
|
||||||
|
*
|
||||||
|
* @param message Message model
|
||||||
|
*/
|
||||||
void add_block_message(model::message &&message);
|
void add_block_message(model::message &&message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief End current block message
|
||||||
|
*
|
||||||
|
* @param message Message model
|
||||||
|
* @param start_type Type of block statement.
|
||||||
|
*/
|
||||||
void end_block_message(
|
void end_block_message(
|
||||||
model::message &&message, common::model::message_t start_type);
|
model::message &&message, common::model::message_t start_type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add `switch` block `case` statement
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
void add_case_stmt_message(model::message &&m);
|
void add_case_stmt_message(model::message &&m);
|
||||||
|
|
||||||
bool started() const;
|
/**
|
||||||
void started(bool s);
|
* @brief Get all sequences in the diagram
|
||||||
|
*
|
||||||
|
* @return Map of sequences in the diagram
|
||||||
|
*/
|
||||||
std::map<common::model::diagram_element::id_t, activity> &sequences();
|
std::map<common::model::diagram_element::id_t, activity> &sequences();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get all sequences in the diagram
|
||||||
|
*
|
||||||
|
* @return Map of sequences in the diagram
|
||||||
|
*/
|
||||||
const std::map<common::model::diagram_element::id_t, activity> &
|
const std::map<common::model::diagram_element::id_t, activity> &
|
||||||
sequences() const;
|
sequences() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get map of all participants in the diagram
|
||||||
|
*
|
||||||
|
* @return Map of participants in the diagram
|
||||||
|
*/
|
||||||
std::map<common::model::diagram_element::id_t, std::unique_ptr<participant>>
|
std::map<common::model::diagram_element::id_t, std::unique_ptr<participant>>
|
||||||
&participants();
|
&participants();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get map of all participants in the diagram
|
||||||
|
*
|
||||||
|
* @return Map of participants in the diagram
|
||||||
|
*/
|
||||||
const std::map<common::model::diagram_element::id_t,
|
const std::map<common::model::diagram_element::id_t,
|
||||||
std::unique_ptr<participant>> &
|
std::unique_ptr<participant>> &
|
||||||
participants() const;
|
participants() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get all active participants in the diagram
|
||||||
|
*
|
||||||
|
* @return Set of all active participant ids
|
||||||
|
*/
|
||||||
std::set<common::model::diagram_element::id_t> &active_participants();
|
std::set<common::model::diagram_element::id_t> &active_participants();
|
||||||
|
|
||||||
const std::set<common::model::diagram_element::id_t> &
|
/**
|
||||||
active_participants() const;
|
* @brief Convert element full name to PlantUML alias.
|
||||||
|
*
|
||||||
|
* @todo This method does not belong here - refactor to PlantUML specific
|
||||||
|
* code.
|
||||||
|
*
|
||||||
|
* @param full_name Full name of the diagram element.
|
||||||
|
* @return PlantUML alias.
|
||||||
|
*/
|
||||||
|
std::string to_alias(const std::string &full_name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return the elements JSON context for inja templates.
|
||||||
|
*
|
||||||
|
* @return JSON node with elements context.
|
||||||
|
*/
|
||||||
|
inja::json context() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug method for printing entire diagram to console.
|
||||||
|
*/
|
||||||
|
void print() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,29 +25,107 @@
|
|||||||
|
|
||||||
namespace clanguml::sequence_diagram::model {
|
namespace clanguml::sequence_diagram::model {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Model of a sequence diagram message.
|
||||||
|
*/
|
||||||
class message : public common::model::diagram_element {
|
class message : public common::model::diagram_element {
|
||||||
public:
|
public:
|
||||||
message() = default;
|
message() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
*
|
||||||
|
* @param type Message type
|
||||||
|
* @param from Id of originating sequence
|
||||||
|
*/
|
||||||
message(common::model::message_t type,
|
message(common::model::message_t type,
|
||||||
common::model::diagram_element::id_t from);
|
common::model::diagram_element::id_t from);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set message type
|
||||||
|
*
|
||||||
|
* @param t Message type
|
||||||
|
*/
|
||||||
void set_type(common::model::message_t t);
|
void set_type(common::model::message_t t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get message type
|
||||||
|
*
|
||||||
|
* @return Message type
|
||||||
|
*/
|
||||||
common::model::message_t type() const;
|
common::model::message_t type() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the id of message source participant
|
||||||
|
*
|
||||||
|
* @param f Id of the participant from which message originates
|
||||||
|
*/
|
||||||
void set_from(common::model::diagram_element::id_t f);
|
void set_from(common::model::diagram_element::id_t f);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the id of source of message
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
common::model::diagram_element::id_t from() const;
|
common::model::diagram_element::id_t from() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the id of the message target
|
||||||
|
*
|
||||||
|
* @param t Id of the message target
|
||||||
|
*/
|
||||||
void set_to(common::model::diagram_element::id_t t);
|
void set_to(common::model::diagram_element::id_t t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the id of the message target
|
||||||
|
*
|
||||||
|
* @return Id of the message target
|
||||||
|
*/
|
||||||
common::model::diagram_element::id_t to() const;
|
common::model::diagram_element::id_t to() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the message label
|
||||||
|
*
|
||||||
|
* @param name Message label
|
||||||
|
*/
|
||||||
void set_message_name(std::string name);
|
void set_message_name(std::string name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the message label
|
||||||
|
*
|
||||||
|
* @return Message label
|
||||||
|
*/
|
||||||
const std::string &message_name() const;
|
const std::string &message_name() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the return message type label
|
||||||
|
*
|
||||||
|
* @param t Message return type label
|
||||||
|
*/
|
||||||
void set_return_type(std::string t);
|
void set_return_type(std::string t);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the return message type label
|
||||||
|
*
|
||||||
|
* @return Message return type label
|
||||||
|
*/
|
||||||
const std::string &return_type() const;
|
const std::string &return_type() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set message scope
|
||||||
|
*
|
||||||
|
* Message scope currently means whether the message was called from
|
||||||
|
* regular statement, or a statement embedded in a statement block condition
|
||||||
|
*
|
||||||
|
* @param scope Message scope
|
||||||
|
*/
|
||||||
void set_message_scope(common::model::message_scope_t scope);
|
void set_message_scope(common::model::message_scope_t scope);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get message scope
|
||||||
|
*
|
||||||
|
* @return Message scope
|
||||||
|
*/
|
||||||
common::model::message_scope_t message_scope() const;
|
common::model::message_scope_t message_scope() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -28,8 +28,16 @@ namespace clanguml::sequence_diagram::model {
|
|||||||
|
|
||||||
using clanguml::common::model::template_trait;
|
using clanguml::common::model::template_trait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Base class for various types of sequence diagram participants
|
||||||
|
*/
|
||||||
struct participant : public common::model::element,
|
struct participant : public common::model::element,
|
||||||
public common::model::stylable_element {
|
public common::model::stylable_element {
|
||||||
|
using common::model::element::element;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enum representing stereotype of a participant
|
||||||
|
*/
|
||||||
enum class stereotype_t {
|
enum class stereotype_t {
|
||||||
participant = 0,
|
participant = 0,
|
||||||
actor,
|
actor,
|
||||||
@@ -41,20 +49,31 @@ struct participant : public common::model::element,
|
|||||||
queue
|
queue
|
||||||
};
|
};
|
||||||
|
|
||||||
using common::model::element::element;
|
|
||||||
|
|
||||||
participant(const participant &) = delete;
|
participant(const participant &) = delete;
|
||||||
participant(participant &&) noexcept = delete;
|
participant(participant &&) noexcept = delete;
|
||||||
participant &operator=(const participant &) = delete;
|
participant &operator=(const participant &) = delete;
|
||||||
participant &operator=(participant &&) = delete;
|
participant &operator=(participant &&) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type name of the diagram element.
|
||||||
|
*
|
||||||
|
* @return Type name of the diagram element.
|
||||||
|
*/
|
||||||
std::string type_name() const override { return "participant"; }
|
std::string type_name() const override { return "participant"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a string representation of the participant
|
||||||
|
*
|
||||||
|
* @return Participant representation as string
|
||||||
|
*/
|
||||||
virtual std::string to_string() const;
|
virtual std::string to_string() const;
|
||||||
|
|
||||||
stereotype_t stereotype_{stereotype_t::participant};
|
stereotype_t stereotype_{stereotype_t::participant};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sequence diagram participant representing a class.
|
||||||
|
*/
|
||||||
struct class_ : public participant, public template_trait {
|
struct class_ : public participant, public template_trait {
|
||||||
public:
|
public:
|
||||||
class_(const common::model::namespace_ &using_namespace);
|
class_(const common::model::namespace_ &using_namespace);
|
||||||
@@ -64,31 +83,104 @@ public:
|
|||||||
class_ &operator=(const class_ &) = delete;
|
class_ &operator=(const class_ &) = delete;
|
||||||
class_ &operator=(class_ &&) = delete;
|
class_ &operator=(class_ &&) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type name of the diagram element.
|
||||||
|
*
|
||||||
|
* @return Type name of the diagram element.
|
||||||
|
*/
|
||||||
std::string type_name() const override { return "class"; }
|
std::string type_name() const override { return "class"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if class is a struct.
|
||||||
|
*
|
||||||
|
* @return True, if the class is declared as struct.
|
||||||
|
*/
|
||||||
bool is_struct() const;
|
bool is_struct() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether the class is a struct.
|
||||||
|
*
|
||||||
|
* @param is_struct True, if the class is declared as struct
|
||||||
|
*/
|
||||||
void is_struct(bool is_struct);
|
void is_struct(bool is_struct);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if class is a template.
|
||||||
|
*
|
||||||
|
* @return True, if the class is a template.
|
||||||
|
*/
|
||||||
bool is_template() const;
|
bool is_template() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether the class is a template instantiation.
|
||||||
|
*
|
||||||
|
* @param is_template True, if the class is a template
|
||||||
|
*/
|
||||||
void is_template(bool is_template);
|
void is_template(bool is_template);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if class is a template instantiation.
|
||||||
|
*
|
||||||
|
* @return True, if the class is a template instantiation.
|
||||||
|
*/
|
||||||
bool is_template_instantiation() const;
|
bool is_template_instantiation() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether the class is a template instantiation.
|
||||||
|
*
|
||||||
|
* @param is_template_instantiation True, if the class is a template
|
||||||
|
* instantiation.
|
||||||
|
*/
|
||||||
void is_template_instantiation(bool is_template_instantiation);
|
void is_template_instantiation(bool is_template_instantiation);
|
||||||
|
|
||||||
friend bool operator==(const class_ &l, const class_ &r);
|
friend bool operator==(const class_ &l, const class_ &r);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return elements full name.
|
||||||
|
*
|
||||||
|
* @return Fully qualified elements name.
|
||||||
|
*/
|
||||||
std::string full_name(bool relative = true) const override;
|
std::string full_name(bool relative = true) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return elements full name but without namespace.
|
||||||
|
*
|
||||||
|
* @return Elements full name without namespace.
|
||||||
|
*/
|
||||||
std::string full_name_no_ns() const override;
|
std::string full_name_no_ns() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if class is a abstract.
|
||||||
|
*
|
||||||
|
* @return True, if the class is abstract.
|
||||||
|
*/
|
||||||
bool is_abstract() const;
|
bool is_abstract() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if class is a typedef/using alias.
|
||||||
|
*
|
||||||
|
* @return True, if the class is a typedef/using alias.
|
||||||
|
*/
|
||||||
bool is_alias() const;
|
bool is_alias() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether the class is an alias
|
||||||
|
*
|
||||||
|
* @param alias True if the class is a typedef/using alias.
|
||||||
|
*/
|
||||||
void is_alias(bool alias);
|
void is_alias(bool alias);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the class is lambda
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
bool is_lambda() const;
|
bool is_lambda() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether the class is a lambda.
|
||||||
|
*
|
||||||
|
* @param is_lambda True, if the class is a lambda
|
||||||
|
*/
|
||||||
void is_lambda(bool is_lambda);
|
void is_lambda(bool is_lambda);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -101,12 +193,23 @@ private:
|
|||||||
std::string full_name_;
|
std::string full_name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Participant representing a C++ lambda.
|
||||||
|
*/
|
||||||
struct lambda : public class_ {
|
struct lambda : public class_ {
|
||||||
using class_::class_;
|
using class_::class_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type name of the diagram element.
|
||||||
|
*
|
||||||
|
* @return Type name of the diagram element.
|
||||||
|
*/
|
||||||
std::string type_name() const override { return "lambda"; }
|
std::string type_name() const override { return "lambda"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Participant mode representing a free function.
|
||||||
|
*/
|
||||||
struct function : public participant {
|
struct function : public participant {
|
||||||
enum class message_render_mode { full, abbreviated, no_arguments };
|
enum class message_render_mode { full, abbreviated, no_arguments };
|
||||||
|
|
||||||
@@ -117,28 +220,92 @@ struct function : public participant {
|
|||||||
function &operator=(const function &) = delete;
|
function &operator=(const function &) = delete;
|
||||||
function &operator=(function &&) = delete;
|
function &operator=(function &&) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type name of the diagram element.
|
||||||
|
*
|
||||||
|
* @return Type name of the diagram element.
|
||||||
|
*/
|
||||||
std::string type_name() const override { return "function"; }
|
std::string type_name() const override { return "function"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return elements full name.
|
||||||
|
*
|
||||||
|
* @return Fully qualified elements name.
|
||||||
|
*/
|
||||||
std::string full_name(bool relative = true) const override;
|
std::string full_name(bool relative = true) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return elements full name but without namespace.
|
||||||
|
*
|
||||||
|
* @return Elements full name without namespace.
|
||||||
|
*/
|
||||||
std::string full_name_no_ns() const override;
|
std::string full_name_no_ns() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Render function name as message label
|
||||||
|
*
|
||||||
|
* @param mode Function argument render mode
|
||||||
|
* @return Message label
|
||||||
|
*/
|
||||||
virtual std::string message_name(message_render_mode mode) const;
|
virtual std::string message_name(message_render_mode mode) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if function is const
|
||||||
|
*
|
||||||
|
* @return True, if function is const
|
||||||
|
*/
|
||||||
bool is_const() const;
|
bool is_const() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether the function is const
|
||||||
|
*
|
||||||
|
* @param c True, if function is const
|
||||||
|
*/
|
||||||
void is_const(bool c);
|
void is_const(bool c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check, if the function has no return value
|
||||||
|
*
|
||||||
|
* @return True, if the function has no return value
|
||||||
|
*/
|
||||||
bool is_void() const;
|
bool is_void() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether the function has a return value
|
||||||
|
*
|
||||||
|
* @param v True, if the function has no return value
|
||||||
|
*/
|
||||||
void is_void(bool v);
|
void is_void(bool v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check, if the function is static
|
||||||
|
*
|
||||||
|
* @return True, if the function is static
|
||||||
|
*/
|
||||||
bool is_static() const;
|
bool is_static() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set whether the function is static
|
||||||
|
*
|
||||||
|
* @param v True, if the function is static
|
||||||
|
*/
|
||||||
void is_static(bool s);
|
void is_static(bool s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add a function parameter
|
||||||
|
*
|
||||||
|
* @note In sequence diagrams we don't care about relationships from
|
||||||
|
* function or method parameters, so we don't need to model them in detail.
|
||||||
|
*
|
||||||
|
* @param a Function parameter label including name and type
|
||||||
|
*/
|
||||||
void add_parameter(const std::string &a);
|
void add_parameter(const std::string &a);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the list of function parameters
|
||||||
|
*
|
||||||
|
* @return List of function parameters
|
||||||
|
*/
|
||||||
const std::vector<std::string> ¶meters() const;
|
const std::vector<std::string> ¶meters() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -148,6 +315,9 @@ private:
|
|||||||
std::vector<std::string> parameters_;
|
std::vector<std::string> parameters_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Participant model representing a method
|
||||||
|
*/
|
||||||
struct method : public function {
|
struct method : public function {
|
||||||
method(const common::model::namespace_ &using_namespace);
|
method(const common::model::namespace_ &using_namespace);
|
||||||
|
|
||||||
@@ -156,26 +326,79 @@ struct method : public function {
|
|||||||
method &operator=(const method &) = delete;
|
method &operator=(const method &) = delete;
|
||||||
method &operator=(method &&) = delete;
|
method &operator=(method &&) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type name of the diagram element.
|
||||||
|
*
|
||||||
|
* @return Type name of the diagram element.
|
||||||
|
*/
|
||||||
std::string type_name() const override { return "method"; }
|
std::string type_name() const override { return "method"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get method name
|
||||||
|
* @return Method name
|
||||||
|
*/
|
||||||
std::string method_name() const;
|
std::string method_name() const;
|
||||||
|
|
||||||
std::string alias() const override;
|
/**
|
||||||
|
* @brief Set method name
|
||||||
|
*
|
||||||
|
* @param name Method name
|
||||||
|
*/
|
||||||
void set_method_name(const std::string &name);
|
void set_method_name(const std::string &name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the participant PlantUML alias
|
||||||
|
*
|
||||||
|
* @todo This method does not belong here - refactor to PlantUML specific
|
||||||
|
* code.
|
||||||
|
*
|
||||||
|
* @return PlantUML alias for the participant to which this method belongs
|
||||||
|
* to.
|
||||||
|
*/
|
||||||
|
std::string alias() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the id of the participant to which this method belongs to.
|
||||||
|
*
|
||||||
|
* @param id Id of the class to which this method belongs to
|
||||||
|
*/
|
||||||
void set_class_id(diagram_element::id_t id);
|
void set_class_id(diagram_element::id_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set full qualified name of the class
|
||||||
|
*
|
||||||
|
* @param name Name of the class including namespace
|
||||||
|
*/
|
||||||
void set_class_full_name(const std::string &name);
|
void set_class_full_name(const std::string &name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the class full name.
|
||||||
|
*
|
||||||
|
* @return Class full name
|
||||||
|
*/
|
||||||
const auto &class_full_name() const;
|
const auto &class_full_name() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return elements full name.
|
||||||
|
*
|
||||||
|
* @return Fully qualified elements name.
|
||||||
|
*/
|
||||||
std::string full_name(bool /*relative*/) const override;
|
std::string full_name(bool /*relative*/) const override;
|
||||||
|
|
||||||
std::string message_name(message_render_mode mode) const override;
|
std::string message_name(message_render_mode mode) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the class id
|
||||||
|
*
|
||||||
|
* @return Class id
|
||||||
|
*/
|
||||||
diagram_element::id_t class_id() const;
|
diagram_element::id_t class_id() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a string representation of the participant
|
||||||
|
*
|
||||||
|
* @return Participant representation as string
|
||||||
|
*/
|
||||||
std::string to_string() const override;
|
std::string to_string() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -184,6 +407,9 @@ private:
|
|||||||
std::string class_full_name_;
|
std::string class_full_name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Participant model representing a function template.
|
||||||
|
*/
|
||||||
struct function_template : public function, public template_trait {
|
struct function_template : public function, public template_trait {
|
||||||
function_template(const common::model::namespace_ &using_namespace);
|
function_template(const common::model::namespace_ &using_namespace);
|
||||||
|
|
||||||
@@ -192,12 +418,33 @@ struct function_template : public function, public template_trait {
|
|||||||
function_template &operator=(const function_template &) = delete;
|
function_template &operator=(const function_template &) = delete;
|
||||||
function_template &operator=(function_template &&) = delete;
|
function_template &operator=(function_template &&) = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type name of the diagram element.
|
||||||
|
*
|
||||||
|
* @return Type name of the diagram element.
|
||||||
|
*/
|
||||||
std::string type_name() const override { return "function_template"; }
|
std::string type_name() const override { return "function_template"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return elements full name.
|
||||||
|
*
|
||||||
|
* @return Fully qualified elements name.
|
||||||
|
*/
|
||||||
std::string full_name(bool relative = true) const override;
|
std::string full_name(bool relative = true) const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return elements full name but without namespace.
|
||||||
|
*
|
||||||
|
* @return Elements full name without namespace.
|
||||||
|
*/
|
||||||
std::string full_name_no_ns() const override;
|
std::string full_name_no_ns() const override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Render function name as message label
|
||||||
|
*
|
||||||
|
* @param mode Function argument render mode
|
||||||
|
* @return Message label
|
||||||
|
*/
|
||||||
std::string message_name(message_render_mode mode) const override;
|
std::string message_name(message_render_mode mode) const override;
|
||||||
};
|
};
|
||||||
} // namespace clanguml::sequence_diagram::model
|
} // namespace clanguml::sequence_diagram::model
|
||||||
|
|||||||
@@ -28,70 +28,268 @@
|
|||||||
|
|
||||||
namespace clanguml::sequence_diagram::visitor {
|
namespace clanguml::sequence_diagram::visitor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This class is used to track current context of the call expressions.
|
||||||
|
*
|
||||||
|
* When traversing AST for call expressions, we need to keep the state of
|
||||||
|
* the current context, for instance whether we are in a `for` loop or
|
||||||
|
* an `if` block, as well as the current parent of the call expression
|
||||||
|
* e.g. a class method or function.
|
||||||
|
*/
|
||||||
struct call_expression_context {
|
struct call_expression_context {
|
||||||
call_expression_context();
|
call_expression_context();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset call expression context to the original state.
|
||||||
|
*/
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void dump();
|
/**
|
||||||
|
* @brief Verify that the context is in a valid state.
|
||||||
|
*
|
||||||
|
* Context can only be in a single state (for instance inside a function).
|
||||||
|
*
|
||||||
|
* @return True, if the context is in a valid state.
|
||||||
|
*/
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @return Current AST context
|
||||||
|
*/
|
||||||
clang::ASTContext *get_ast_context() const;
|
clang::ASTContext *get_ast_context() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the current context to a class.
|
||||||
|
*
|
||||||
|
* @param cls Class declaration.
|
||||||
|
*/
|
||||||
void update(clang::CXXRecordDecl *cls);
|
void update(clang::CXXRecordDecl *cls);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the current context to a class template specialization.
|
||||||
|
*
|
||||||
|
* @param clst Class template specialization declaration.
|
||||||
|
*/
|
||||||
void update(clang::ClassTemplateSpecializationDecl *clst);
|
void update(clang::ClassTemplateSpecializationDecl *clst);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the current context to a class template.
|
||||||
|
*
|
||||||
|
* @param clst Class template declaration.
|
||||||
|
*/
|
||||||
void update(clang::ClassTemplateDecl *clst);
|
void update(clang::ClassTemplateDecl *clst);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the current context to a class method.
|
||||||
|
*
|
||||||
|
* @param method Class method declaration.
|
||||||
|
*/
|
||||||
void update(clang::CXXMethodDecl *method);
|
void update(clang::CXXMethodDecl *method);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the current context to a function.
|
||||||
|
*
|
||||||
|
* @param function Function declaration.
|
||||||
|
*/
|
||||||
void update(clang::FunctionDecl *function);
|
void update(clang::FunctionDecl *function);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the current context to a function template.
|
||||||
|
*
|
||||||
|
* @param function_template Function template declaration.
|
||||||
|
*/
|
||||||
void update(clang::FunctionTemplateDecl *function_template);
|
void update(clang::FunctionTemplateDecl *function_template);
|
||||||
|
|
||||||
std::int64_t caller_id() const;
|
/**
|
||||||
|
* @brief Set current caller to id of the current participant.
|
||||||
std::int64_t lambda_caller_id() const;
|
*
|
||||||
|
* @param id Set current caller id.
|
||||||
|
*/
|
||||||
void set_caller_id(std::int64_t id);
|
void set_caller_id(std::int64_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current caller id
|
||||||
|
*
|
||||||
|
* @return Id of the current caller participant
|
||||||
|
*/
|
||||||
|
std::int64_t caller_id() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the id of the current lambda caller.
|
||||||
|
*
|
||||||
|
* Since lambdas can be nested within methods and functions, they have
|
||||||
|
* a separate caller id field.
|
||||||
|
*
|
||||||
|
* @return Current lambda caller id, or 0 if current caller is not lambda.
|
||||||
|
*/
|
||||||
|
std::int64_t lambda_caller_id() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enter a lambda expression
|
||||||
|
*
|
||||||
|
* @param id Lambda id
|
||||||
|
*/
|
||||||
void enter_lambda_expression(std::int64_t id);
|
void enter_lambda_expression(std::int64_t id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Leave current lambda expression
|
||||||
|
*/
|
||||||
void leave_lambda_expression();
|
void leave_lambda_expression();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current `if` statement block
|
||||||
|
*
|
||||||
|
* @return `if` statement block.
|
||||||
|
*/
|
||||||
clang::IfStmt *current_ifstmt() const;
|
clang::IfStmt *current_ifstmt() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enter `if` statement block
|
||||||
|
*
|
||||||
|
* @param stmt `if` statement block
|
||||||
|
*/
|
||||||
void enter_ifstmt(clang::IfStmt *stmt);
|
void enter_ifstmt(clang::IfStmt *stmt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Leave `if` statement block
|
||||||
|
*/
|
||||||
void leave_ifstmt();
|
void leave_ifstmt();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enter `else if` statement block
|
||||||
|
*
|
||||||
|
* @param stmt `if` statement block
|
||||||
|
*/
|
||||||
void enter_elseifstmt(clang::IfStmt *stmt);
|
void enter_elseifstmt(clang::IfStmt *stmt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current `else if` statement block
|
||||||
|
*
|
||||||
|
* @return `if` statement block.
|
||||||
|
*/
|
||||||
clang::IfStmt *current_elseifstmt() const;
|
clang::IfStmt *current_elseifstmt() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current loop statement block
|
||||||
|
*
|
||||||
|
* @return Loop statement block.
|
||||||
|
*/
|
||||||
clang::Stmt *current_loopstmt() const;
|
clang::Stmt *current_loopstmt() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enter loop statement block
|
||||||
|
*
|
||||||
|
* @param stmt Loop statement block
|
||||||
|
*/
|
||||||
void enter_loopstmt(clang::Stmt *stmt);
|
void enter_loopstmt(clang::Stmt *stmt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Leave loop statement block
|
||||||
|
*/
|
||||||
void leave_loopstmt();
|
void leave_loopstmt();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current `try` statement block
|
||||||
|
*
|
||||||
|
* @return `try` statement block.
|
||||||
|
*/
|
||||||
clang::Stmt *current_trystmt() const;
|
clang::Stmt *current_trystmt() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enter `try` statement block
|
||||||
|
*
|
||||||
|
* @param stmt `try` statement block
|
||||||
|
*/
|
||||||
void enter_trystmt(clang::Stmt *stmt);
|
void enter_trystmt(clang::Stmt *stmt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Leave `try` statement block
|
||||||
|
*/
|
||||||
void leave_trystmt();
|
void leave_trystmt();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current `switch` statement block
|
||||||
|
*
|
||||||
|
* @return `switch` statement block.
|
||||||
|
*/
|
||||||
clang::SwitchStmt *current_switchstmt() const;
|
clang::SwitchStmt *current_switchstmt() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enter `switch` statement block
|
||||||
|
*
|
||||||
|
* @param stmt `switch` statement block
|
||||||
|
*/
|
||||||
void enter_switchstmt(clang::SwitchStmt *stmt);
|
void enter_switchstmt(clang::SwitchStmt *stmt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Leave `switch` statement block
|
||||||
|
*/
|
||||||
void leave_switchstmt();
|
void leave_switchstmt();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current `:?` statement block
|
||||||
|
*
|
||||||
|
* @return `:?` statement block.
|
||||||
|
*/
|
||||||
clang::ConditionalOperator *current_conditionaloperator() const;
|
clang::ConditionalOperator *current_conditionaloperator() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enter `:?` statement block
|
||||||
|
*
|
||||||
|
* @param stmt `:?` statement block
|
||||||
|
*/
|
||||||
void enter_conditionaloperator(clang::ConditionalOperator *stmt);
|
void enter_conditionaloperator(clang::ConditionalOperator *stmt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Leave `:?` statement block
|
||||||
|
*/
|
||||||
void leave_conditionaloperator();
|
void leave_conditionaloperator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current call expression
|
||||||
|
*
|
||||||
|
* @return Call expression
|
||||||
|
*/
|
||||||
clang::CallExpr *current_callexpr() const;
|
clang::CallExpr *current_callexpr() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enter a call expression
|
||||||
|
*
|
||||||
|
* @param stmt Call expression
|
||||||
|
*/
|
||||||
void enter_callexpr(clang::CallExpr *expr);
|
void enter_callexpr(clang::CallExpr *expr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Leave call expression
|
||||||
|
*/
|
||||||
void leave_callexpr();
|
void leave_callexpr();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check, if a statement is contained in a control statement
|
||||||
|
*
|
||||||
|
* This method is used to check if `stmt` is contained in control
|
||||||
|
* statement of a block, for instance:
|
||||||
|
*
|
||||||
|
* ```cpp
|
||||||
|
* if(a.method1()) {}
|
||||||
|
* ```
|
||||||
|
* it will return `true` for `stmt` representing `method1()` call
|
||||||
|
* expression.
|
||||||
|
*
|
||||||
|
* @param stmt Statement
|
||||||
|
* @return True, if `stmt` is contained in control expression of a
|
||||||
|
* statement block
|
||||||
|
*/
|
||||||
bool is_expr_in_current_control_statement_condition(
|
bool is_expr_in_current_control_statement_condition(
|
||||||
const clang::Stmt *stmt) const;
|
const clang::Stmt *stmt) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Print the current call expression stack for debugging.
|
||||||
|
*/
|
||||||
|
void dump();
|
||||||
|
|
||||||
clang::CXXRecordDecl *current_class_decl_{nullptr};
|
clang::CXXRecordDecl *current_class_decl_{nullptr};
|
||||||
clang::ClassTemplateDecl *current_class_template_decl_{nullptr};
|
clang::ClassTemplateDecl *current_class_template_decl_{nullptr};
|
||||||
clang::ClassTemplateSpecializationDecl
|
clang::ClassTemplateSpecializationDecl
|
||||||
|
|||||||
@@ -35,16 +35,33 @@ using common::model::template_parameter;
|
|||||||
|
|
||||||
std::string to_string(const clang::FunctionTemplateDecl *decl);
|
std::string to_string(const clang::FunctionTemplateDecl *decl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sequence diagram translation unit visitor
|
||||||
|
*
|
||||||
|
* This class implements the `clang::RecursiveASTVisitor` interface
|
||||||
|
* for selected visitors relevant to generating sequence diagrams.
|
||||||
|
*/
|
||||||
class translation_unit_visitor
|
class translation_unit_visitor
|
||||||
: public clang::RecursiveASTVisitor<translation_unit_visitor>,
|
: public clang::RecursiveASTVisitor<translation_unit_visitor>,
|
||||||
public common::visitor::translation_unit_visitor {
|
public common::visitor::translation_unit_visitor {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Constructor.
|
||||||
|
*
|
||||||
|
* @param sm Current source manager reference
|
||||||
|
* @param diagram Diagram model
|
||||||
|
* @param config Diagram configuration
|
||||||
|
*/
|
||||||
translation_unit_visitor(clang::SourceManager &sm,
|
translation_unit_visitor(clang::SourceManager &sm,
|
||||||
clanguml::sequence_diagram::model::diagram &diagram,
|
clanguml::sequence_diagram::model::diagram &diagram,
|
||||||
const clanguml::config::sequence_diagram &config);
|
const clanguml::config::sequence_diagram &config);
|
||||||
|
|
||||||
~translation_unit_visitor() override = default;
|
~translation_unit_visitor() override = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \defgroup Implementation of ResursiveASTVisitor methods
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
bool shouldVisitTemplateInstantiations();
|
bool shouldVisitTemplateInstantiations();
|
||||||
|
|
||||||
bool VisitCallExpr(clang::CallExpr *expr);
|
bool VisitCallExpr(clang::CallExpr *expr);
|
||||||
@@ -99,19 +116,50 @@ public:
|
|||||||
bool TraverseDefaultStmt(clang::DefaultStmt *stmt);
|
bool TraverseDefaultStmt(clang::DefaultStmt *stmt);
|
||||||
|
|
||||||
bool TraverseConditionalOperator(clang::ConditionalOperator *stmt);
|
bool TraverseConditionalOperator(clang::ConditionalOperator *stmt);
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get diagram model reference
|
||||||
|
*
|
||||||
|
* @return Reference to diagram model created by the visitor
|
||||||
|
*/
|
||||||
clanguml::sequence_diagram::model::diagram &diagram();
|
clanguml::sequence_diagram::model::diagram &diagram();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get diagram model reference
|
||||||
|
*
|
||||||
|
* @return Reference to diagram model created by the visitor
|
||||||
|
*/
|
||||||
const clanguml::sequence_diagram::model::diagram &diagram() const;
|
const clanguml::sequence_diagram::model::diagram &diagram() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get diagram config instance
|
||||||
|
*
|
||||||
|
* @return Reference to config instance
|
||||||
|
*/
|
||||||
const clanguml::config::sequence_diagram &config() const;
|
const clanguml::config::sequence_diagram &config() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current call expression context reference
|
||||||
|
*
|
||||||
|
* @return Reference to the current call expression context
|
||||||
|
*/
|
||||||
call_expression_context &context();
|
call_expression_context &context();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current call expression context reference
|
||||||
|
*
|
||||||
|
* @return Reference to the current call expression context
|
||||||
|
*/
|
||||||
const call_expression_context &context() const;
|
const call_expression_context &context() const;
|
||||||
|
|
||||||
void finalize();
|
/**
|
||||||
|
* @brief Get participant by declaration
|
||||||
|
*
|
||||||
|
* @tparam T Participant type
|
||||||
|
* @param decl Clang entity declaration
|
||||||
|
* @return Optional reference to participant diagram element
|
||||||
|
*/
|
||||||
template <typename T = model::participant>
|
template <typename T = model::participant>
|
||||||
common::optional_ref<T> get_participant(const clang::Decl *decl)
|
common::optional_ref<T> get_participant(const clang::Decl *decl)
|
||||||
{
|
{
|
||||||
@@ -124,6 +172,13 @@ public:
|
|||||||
return get_participant<T>(unique_participant_id.value());
|
return get_participant<T>(unique_participant_id.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get participant by declaration
|
||||||
|
*
|
||||||
|
* @tparam T Participant type
|
||||||
|
* @param decl Clang entity declaration
|
||||||
|
* @return Optional reference to participant diagram element
|
||||||
|
*/
|
||||||
template <typename T = model::participant>
|
template <typename T = model::participant>
|
||||||
common::optional_ref<T> get_participant(const clang::Decl *decl) const
|
common::optional_ref<T> get_participant(const clang::Decl *decl) const
|
||||||
{
|
{
|
||||||
@@ -136,6 +191,13 @@ public:
|
|||||||
return get_participant<T>(unique_participant_id.value());
|
return get_participant<T>(unique_participant_id.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get participant by global element id
|
||||||
|
*
|
||||||
|
* @tparam T Participant type
|
||||||
|
* @param id Global element id
|
||||||
|
* @return Optional reference to participant diagram element
|
||||||
|
*/
|
||||||
template <typename T = model::participant>
|
template <typename T = model::participant>
|
||||||
common::optional_ref<T> get_participant(
|
common::optional_ref<T> get_participant(
|
||||||
const common::model::diagram_element::id_t id)
|
const common::model::diagram_element::id_t id)
|
||||||
@@ -147,6 +209,13 @@ public:
|
|||||||
*(static_cast<T *>(diagram().participants().at(id).get())));
|
*(static_cast<T *>(diagram().participants().at(id).get())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get participant by global element id
|
||||||
|
*
|
||||||
|
* @tparam T Participant type
|
||||||
|
* @param id Global element id
|
||||||
|
* @return Optional reference to participant diagram element
|
||||||
|
*/
|
||||||
template <typename T = model::participant>
|
template <typename T = model::participant>
|
||||||
common::optional_ref<T> get_participant(
|
common::optional_ref<T> get_participant(
|
||||||
common::model::diagram_element::id_t id) const
|
common::model::diagram_element::id_t id) const
|
||||||
@@ -158,24 +227,94 @@ public:
|
|||||||
*(static_cast<T *>(diagram().participants().at(id).get())));
|
*(static_cast<T *>(diagram().participants().at(id).get())));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Store the mapping from local clang entity id (obtained using
|
/**
|
||||||
/// getID()) method to clang-uml global id
|
* @brief Store the mapping from local clang entity id (obtained using
|
||||||
|
* getID()) method to clang-uml global id
|
||||||
|
*
|
||||||
|
* @todo Refactor to @ref ast_id_mapper
|
||||||
|
*
|
||||||
|
* @param local_id Local AST element id
|
||||||
|
* @param global_id Globa diagram element id
|
||||||
|
*/
|
||||||
void set_unique_id(
|
void set_unique_id(
|
||||||
int64_t local_id, common::model::diagram_element::id_t global_id);
|
int64_t local_id, common::model::diagram_element::id_t global_id);
|
||||||
|
|
||||||
/// Retrieve the global clang-uml entity id based on the clang local id
|
/**
|
||||||
|
* @brief Retrieve the global `clang-uml` entity id based on the Clang
|
||||||
|
* local id
|
||||||
|
* @param local_id AST local element id
|
||||||
|
* @return Global diagram element id
|
||||||
|
*/
|
||||||
std::optional<common::model::diagram_element::id_t> get_unique_id(
|
std::optional<common::model::diagram_element::id_t> get_unique_id(
|
||||||
int64_t local_id) const;
|
int64_t local_id) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Finalize diagram model
|
||||||
|
*/
|
||||||
|
void finalize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* @brief Check if the diagram should include a declaration.
|
||||||
|
*
|
||||||
|
* @param decl Clang declaration.
|
||||||
|
* @return True, if the entity should be included in the diagram.
|
||||||
|
*/
|
||||||
bool should_include(const clang::TagDecl *decl) const;
|
bool should_include(const clang::TagDecl *decl) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the diagram should include a lambda expression.
|
||||||
|
*
|
||||||
|
* @param expr Lambda expression.
|
||||||
|
* @return True, if the expression should be included in the diagram.
|
||||||
|
*/
|
||||||
bool should_include(const clang::LambdaExpr *expr) const;
|
bool should_include(const clang::LambdaExpr *expr) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the diagram should include a call expression.
|
||||||
|
*
|
||||||
|
* @param expr Call expression.
|
||||||
|
* @return True, if the expression should be included in the diagram.
|
||||||
|
*/
|
||||||
bool should_include(const clang::CallExpr *expr) const;
|
bool should_include(const clang::CallExpr *expr) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the diagram should include a declaration.
|
||||||
|
*
|
||||||
|
* @param decl Clang declaration.
|
||||||
|
* @return True, if the entity should be included in the diagram.
|
||||||
|
*/
|
||||||
bool should_include(const clang::CXXMethodDecl *decl) const;
|
bool should_include(const clang::CXXMethodDecl *decl) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the diagram should include a declaration.
|
||||||
|
*
|
||||||
|
* @param decl Clang declaration.
|
||||||
|
* @return True, if the entity should be included in the diagram.
|
||||||
|
*/
|
||||||
bool should_include(const clang::FunctionDecl *decl) const;
|
bool should_include(const clang::FunctionDecl *decl) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the diagram should include a declaration.
|
||||||
|
*
|
||||||
|
* @param decl Clang declaration.
|
||||||
|
* @return True, if the entity should be included in the diagram.
|
||||||
|
*/
|
||||||
bool should_include(const clang::FunctionTemplateDecl *decl) const;
|
bool should_include(const clang::FunctionTemplateDecl *decl) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the diagram should include a declaration.
|
||||||
|
*
|
||||||
|
* @param decl Clang declaration.
|
||||||
|
* @return True, if the entity should be included in the diagram.
|
||||||
|
*/
|
||||||
bool should_include(const clang::ClassTemplateDecl *decl) const;
|
bool should_include(const clang::ClassTemplateDecl *decl) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo Refactor this group of methods to @ref template_builder
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
std::unique_ptr<clanguml::sequence_diagram::model::class_>
|
std::unique_ptr<clanguml::sequence_diagram::model::class_>
|
||||||
create_class_model(clang::CXXRecordDecl *cls);
|
create_class_model(clang::CXXRecordDecl *cls);
|
||||||
|
|
||||||
@@ -251,31 +390,107 @@ private:
|
|||||||
const std::string &full_name) const;
|
const std::string &full_name) const;
|
||||||
|
|
||||||
std::string simplify_system_template(const std::string &full_name) const;
|
std::string simplify_system_template(const std::string &full_name) const;
|
||||||
|
/** }@ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assuming `cls` is a lambda, create it's full name.
|
||||||
|
*
|
||||||
|
* @note Currently, lambda names are generated using their source code
|
||||||
|
* location including file path, line and column to ensure
|
||||||
|
* unique names.
|
||||||
|
*
|
||||||
|
* @param cls Lambda declaration
|
||||||
|
* @return Full lambda unique name
|
||||||
|
*/
|
||||||
std::string make_lambda_name(const clang::CXXRecordDecl *cls) const;
|
std::string make_lambda_name(const clang::CXXRecordDecl *cls) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if template is a smart pointer
|
||||||
|
*
|
||||||
|
* @param primary_template Template declaration
|
||||||
|
* @return True, if template declaration is a smart pointer
|
||||||
|
*/
|
||||||
bool is_smart_pointer(const clang::TemplateDecl *primary_template) const;
|
bool is_smart_pointer(const clang::TemplateDecl *primary_template) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check, the callee is a template specialization
|
||||||
|
*
|
||||||
|
* @param dependent_member_expr Dependent member expression
|
||||||
|
* @return True, if the callee is a template specialization
|
||||||
|
*/
|
||||||
bool is_callee_valid_template_specialization(
|
bool is_callee_valid_template_specialization(
|
||||||
const clang::CXXDependentScopeMemberExpr *dependent_member_expr) const;
|
const clang::CXXDependentScopeMemberExpr *dependent_member_expr) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle a operator call expresion
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
* @param operator_call_expr Operator call expression
|
||||||
|
* @return True, if `m` contains now a valid call expression model
|
||||||
|
*/
|
||||||
bool process_operator_call_expression(model::message &m,
|
bool process_operator_call_expression(model::message &m,
|
||||||
const clang::CXXOperatorCallExpr *operator_call_expr);
|
const clang::CXXOperatorCallExpr *operator_call_expr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle a class method call expresion
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
* @param method_call_expr Operator call expression
|
||||||
|
* @return True, if `m` contains now a valid call expression model
|
||||||
|
*/
|
||||||
bool process_class_method_call_expression(
|
bool process_class_method_call_expression(
|
||||||
model::message &m, const clang::CXXMemberCallExpr *operator_call_expr);
|
model::message &m, const clang::CXXMemberCallExpr *method_call_expr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle a class template method call expresion
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
* @param expr Class template method call expression
|
||||||
|
* @return True, if `m` contains now a valid call expression model
|
||||||
|
*/
|
||||||
bool process_class_template_method_call_expression(
|
bool process_class_template_method_call_expression(
|
||||||
model::message &m, const clang::CallExpr *expr);
|
model::message &m, const clang::CallExpr *expr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle a function call expresion
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
* @param expr Function call expression
|
||||||
|
* @return True, if `m` contains now a valid call expression model
|
||||||
|
*/
|
||||||
bool process_function_call_expression(
|
bool process_function_call_expression(
|
||||||
model::message &m, const clang::CallExpr *expr);
|
model::message &m, const clang::CallExpr *expr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Handle an unresolved lookup call expresion
|
||||||
|
*
|
||||||
|
* Unresolved lookup expression is a reference to a name which Clang was
|
||||||
|
* not able to look up during parsing but could not resolve to a
|
||||||
|
* specific declaration.
|
||||||
|
*
|
||||||
|
* @param m Message model
|
||||||
|
* @param expr Call expression
|
||||||
|
* @return True, if `m` contains now a valid call expression model
|
||||||
|
*/
|
||||||
bool process_unresolved_lookup_call_expression(
|
bool process_unresolved_lookup_call_expression(
|
||||||
model::message &m, const clang::CallExpr *expr) const;
|
model::message &m, const clang::CallExpr *expr) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register a message model `m` with a call expression
|
||||||
|
*
|
||||||
|
* This is used to know whether a model for a specific call expression
|
||||||
|
* has already been created, but not yet added to the diagram.
|
||||||
|
*
|
||||||
|
* @param expr Call expresion
|
||||||
|
* @param m Message model
|
||||||
|
*/
|
||||||
void push_message(clang::CallExpr *expr, model::message &&m);
|
void push_message(clang::CallExpr *expr, model::message &&m);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Move a message model to diagram.
|
||||||
|
*
|
||||||
|
* @param expr Call expression
|
||||||
|
*/
|
||||||
void pop_message_to_diagram(clang::CallExpr *expr);
|
void pop_message_to_diagram(clang::CallExpr *expr);
|
||||||
|
|
||||||
// Reference to the output diagram model
|
// Reference to the output diagram model
|
||||||
@@ -286,16 +501,20 @@ private:
|
|||||||
|
|
||||||
call_expression_context call_expression_context_;
|
call_expression_context call_expression_context_;
|
||||||
|
|
||||||
/// This is used to generate messages in proper order in case of
|
/**
|
||||||
/// nested call expressions (e.g. a(b(c(), d())), as they need to
|
* This is used to generate messages in proper order in case of nested call
|
||||||
/// be added to the diagram sequence after the visitor leaves the
|
* expressions (e.g. a(b(c(), d())), as they need to be added to the diagram
|
||||||
/// call expression AST node
|
* sequence after the visitor leaves the call expression AST node
|
||||||
|
*/
|
||||||
std::map<clang::CallExpr *, model::message> call_expr_message_map_;
|
std::map<clang::CallExpr *, model::message> call_expr_message_map_;
|
||||||
|
|
||||||
std::map<common::model::diagram_element::id_t,
|
std::map<common::model::diagram_element::id_t,
|
||||||
std::unique_ptr<clanguml::sequence_diagram::model::class_>>
|
std::unique_ptr<clanguml::sequence_diagram::model::class_>>
|
||||||
forward_declarations_;
|
forward_declarations_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo Refactor to @ref ast_id_mapper
|
||||||
|
*/
|
||||||
std::map</* local id from ->getID() */ int64_t,
|
std::map</* local id from ->getID() */ int64_t,
|
||||||
/* global ID based on full name */ common::model::diagram_element::id_t>
|
/* global ID based on full name */ common::model::diagram_element::id_t>
|
||||||
local_ast_id_map_;
|
local_ast_id_map_;
|
||||||
|
|||||||
@@ -2571,4 +2571,9 @@ h2:hover a.anchorlink, h1:hover a.anchorlink, h3:hover a.anchorlink, h4:hover a.
|
|||||||
/* Preserve newlines in highlight.js code blocks */
|
/* Preserve newlines in highlight.js code blocks */
|
||||||
div.hljs {
|
div.hljs {
|
||||||
white-space: pre;
|
white-space: pre;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.copyright {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
type: class
|
type: class
|
||||||
include_relations_also_as_members: false
|
include_relations_also_as_members: true
|
||||||
generate_method_arguments: none
|
generate_method_arguments: none
|
||||||
|
generate_packages: true
|
||||||
glob:
|
glob:
|
||||||
- src/common/model/*.cc
|
- src/common/model/*.cc
|
||||||
- src/sequence_diagram/model/*.cc
|
- src/sequence_diagram/model/*.cc
|
||||||
@@ -8,11 +9,21 @@ include:
|
|||||||
namespaces:
|
namespaces:
|
||||||
- clanguml::common::model
|
- clanguml::common::model
|
||||||
- clanguml::sequence_diagram::model
|
- clanguml::sequence_diagram::model
|
||||||
|
context:
|
||||||
|
- clanguml::sequence_diagram::model::diagram
|
||||||
|
- clanguml::sequence_diagram::model::message
|
||||||
|
- clanguml::sequence_diagram::model::activity
|
||||||
|
subclasses:
|
||||||
|
- clanguml::sequence_diagram::model::participant
|
||||||
exclude:
|
exclude:
|
||||||
relationships:
|
relationships:
|
||||||
- dependency
|
- dependency
|
||||||
|
method_types:
|
||||||
|
- constructor
|
||||||
|
- destructor
|
||||||
|
- operator
|
||||||
using_namespace:
|
using_namespace:
|
||||||
- clanguml::sequence_diagram::model
|
- clanguml
|
||||||
plantuml:
|
plantuml:
|
||||||
before:
|
before:
|
||||||
- 'title clang-uml sequence diagram model'
|
- 'title clang-uml sequence diagram model'
|
||||||
@@ -29,6 +29,12 @@ with open(r'tests/test_cases.yaml') as f:
|
|||||||
# Generate test_cases.md index
|
# Generate test_cases.md index
|
||||||
with open(r'docs/test_cases.md', 'w') as tc_index:
|
with open(r'docs/test_cases.md', 'w') as tc_index:
|
||||||
tc_index.write('# Test cases index\n')
|
tc_index.write('# Test cases index\n')
|
||||||
|
tc_index.write("* [Class diagrams](#class-diagrams)")
|
||||||
|
tc_index.write("* [Sequence diagrams](#sequence-diagrams)")
|
||||||
|
tc_index.write("* [Package diagrams](#package-diagrams)")
|
||||||
|
tc_index.write("* [Include diagrams](#include-diagrams)")
|
||||||
|
tc_index.write("* [Other diagrams](#other-diagrams)")
|
||||||
|
tc_index.write(" ")
|
||||||
for test_group, test_cases in test_groups.items():
|
for test_group, test_cases in test_groups.items():
|
||||||
tc_index.write(f'## {test_group}\n')
|
tc_index.write(f'## {test_group}\n')
|
||||||
for test_case in test_cases:
|
for test_case in test_cases:
|
||||||
|
|||||||
Reference in New Issue
Block a user