0.5.4
C++ to UML diagram generator based on Clang
Loading...
Searching...
No Matches
Public Member Functions | Private Member Functions | List of all members
clanguml::common::visitor::comment::clang_visitor Class Reference

Uses Clang's comment parser to extract Doxygen-style comment blocks. More...

Detailed Description

Uses Clang's comment parser to extract Doxygen-style comment blocks.

Definition at line 31 of file clang_visitor.h.

#include <clang_visitor.h>

Public Member Functions

 clang_visitor (clang::SourceManager &source_manager)
 
void visit (const clang::NamedDecl &decl, common::model::decorated_element &e) override
 
- Public Member Functions inherited from clanguml::common::visitor::comment::comment_visitor
 comment_visitor (clang::SourceManager &source_manager)
 
virtual ~comment_visitor ()=default
 
virtual void visit (const clang::NamedDecl &decl, common::model::decorated_element &e)=0
 
clang::SourceManager & source_manager ()
 

Private Member Functions

void visit_block_command (const clang::comments::BlockCommandComment *command, const clang::comments::CommandTraits &traits, common::model::comment_t &cmt)
 
void visit_param_command (const clang::comments::ParamCommandComment *command, const clang::comments::CommandTraits &traits, common::model::comment_t &cmt)
 
void visit_tparam_command (const clang::comments::TParamCommandComment *command, const clang::comments::CommandTraits &traits, common::model::comment_t &cmt)
 
void visit_paragraph (const clang::comments::ParagraphComment *paragraph, const clang::comments::CommandTraits &traits, std::string &text)
 

Constructor & Destructor Documentation

◆ clang_visitor()

clanguml::common::visitor::comment::clang_visitor::clang_visitor ( clang::SourceManager &  source_manager)

Definition at line 32 of file clang_visitor.cc.

Member Function Documentation

◆ visit()

void clanguml::common::visitor::comment::clang_visitor::visit ( const clang::NamedDecl &  decl,
common::model::decorated_element e 
)
overridevirtual

Extracts Doxygen style comment blocks from the comment.

Parameters
declClang's named declaration
eDiagram element

Implements clanguml::common::visitor::comment::comment_visitor.

Definition at line 37 of file clang_visitor.cc.

39{
40 const auto *comment =
41 decl.getASTContext().getRawCommentForDeclNoCache(&decl);
42
43 if (comment == nullptr) {
44 return;
45 }
46
47 auto raw_comment = comment->getRawText(source_manager());
48
49 auto formatted_comment = comment->getFormattedText(
50 source_manager(), decl.getASTContext().getDiagnostics());
51
52 common::model::comment_t cmt = inja::json::object();
53 cmt["raw"] = raw_comment;
54 cmt["formatted"] = formatted_comment;
55
56 using clang::comments::BlockCommandComment;
57 using clang::comments::FullComment;
58 using clang::comments::ParagraphComment;
59 using clang::comments::ParamCommandComment;
60 using clang::comments::TextComment;
61 using clang::comments::TParamCommandComment;
62
63 FullComment *full_comment =
64 comment->parse(decl.getASTContext(), nullptr, &decl);
65
66 const auto &traits = decl.getASTContext().getCommentCommandTraits();
67
68 for (const auto *block : full_comment->getBlocks()) {
69 const auto block_kind = block->getCommentKind();
70 if (block_kind == CLANG_UML_LLVM_COMMENT_KIND(ParagraphComment)) {
71 std::string paragraph_text;
72
73 visit_paragraph(clang::dyn_cast<ParagraphComment>(block), traits,
74 paragraph_text);
75 if (!cmt.contains("text"))
76 cmt["text"] = "";
77
78 cmt["text"] =
79 cmt["text"].get<std::string>() + "\n" + paragraph_text;
80
81 if (!cmt.contains("paragraph"))
82 cmt["paragraph"] = inja::json::array();
83
84 cmt["paragraph"].push_back(paragraph_text);
85 }
86 else if (block_kind == CLANG_UML_LLVM_COMMENT_KIND(TextComment)) {
87 // TODO
88 }
89 else if (block_kind ==
90 CLANG_UML_LLVM_COMMENT_KIND(ParamCommandComment)) {
92 clang::dyn_cast<ParamCommandComment>(block), traits, cmt);
93 }
94 else if (block_kind ==
95 CLANG_UML_LLVM_COMMENT_KIND(TParamCommandComment)) {
97 clang::dyn_cast<TParamCommandComment>(block), traits, cmt);
98 }
99 else if (block_kind ==
100 CLANG_UML_LLVM_COMMENT_KIND(BlockCommandComment)) {
101 if (const auto *command =
102 clang::dyn_cast<BlockCommandComment>(block);
103 command != nullptr) {
104 const auto *command_info =
105 traits.getCommandInfo(command->getCommandID());
106
107 if (command_info->IsBlockCommand &&
108 command_info->NumArgs == 0U) {
109 // Visit block command with a single text argument, e.g.:
110 // \brief text
111 // \todo text
112 // ...
113 visit_block_command(command, traits, cmt);
114 }
115 else if (command_info->IsParamCommand) {
116 // Visit function param block:
117 // \param arg text
119 clang::dyn_cast<ParamCommandComment>(command), traits,
120 cmt);
121 }
122 else if (command_info->IsTParamCommand) {
123 // Visit template param block:
124 // \tparam typename text
126 clang::dyn_cast<TParamCommandComment>(command), traits,
127 cmt);
128 }
129 }
130 }
131 }
132 e.set_comment(cmt);
133}

◆ visit_block_command()

void clanguml::common::visitor::comment::clang_visitor::visit_block_command ( const clang::comments::BlockCommandComment *  command,
const clang::comments::CommandTraits &  traits,
common::model::comment_t cmt 
)
private

Definition at line 135 of file clang_visitor.cc.

138{
139 using clang::comments::Comment;
140 using clang::comments::ParagraphComment;
141 using clang::comments::TextComment;
142
143 std::string command_text;
144
145 for (const auto *paragraph_it = command->child_begin();
146 paragraph_it != command->child_end(); ++paragraph_it) {
147
148 if ((*paragraph_it)->getCommentKind() ==
149 CLANG_UML_LLVM_COMMENT_KIND(ParagraphComment)) {
150 visit_paragraph(clang::dyn_cast<ParagraphComment>(*paragraph_it),
151 traits, command_text);
152 }
153 }
154
155 const auto command_name = command->getCommandName(traits).str();
156 if (!command_text.empty()) {
157 if (!cmt.contains(command_name))
158 cmt[command_name] = inja::json::array();
159
160 cmt[command_name].push_back(command_text);
161 }
162}

◆ visit_paragraph()

void clanguml::common::visitor::comment::clang_visitor::visit_paragraph ( const clang::comments::ParagraphComment *  paragraph,
const clang::comments::CommandTraits &  traits,
std::string &  text 
)
private

Definition at line 235 of file clang_visitor.cc.

238{
239 using clang::comments::Comment;
240 using clang::comments::TextComment;
241
242 if (paragraph == nullptr)
243 return;
244
245 for (const auto *text_it = paragraph->child_begin();
246 text_it != paragraph->child_end(); ++text_it) {
247
248 if ((*text_it)->getCommentKind() ==
249 CLANG_UML_LLVM_COMMENT_KIND(TextComment) &&
250 clang::dyn_cast<TextComment>(*text_it) != nullptr) {
251 // Merge paragraph lines into a single string
252 text += clang::dyn_cast<TextComment>(*text_it)->getText();
253 text += "\n";
254 }
255 }
256}

◆ visit_param_command()

void clanguml::common::visitor::comment::clang_visitor::visit_param_command ( const clang::comments::ParamCommandComment *  command,
const clang::comments::CommandTraits &  traits,
common::model::comment_t cmt 
)
private

Definition at line 164 of file clang_visitor.cc.

167{
168 using clang::comments::Comment;
169 using clang::comments::ParagraphComment;
170 using clang::comments::TextComment;
171
172 std::string description;
173
174 if (command == nullptr)
175 return;
176
177 const auto name = command->getParamNameAsWritten().str();
178
179 for (const auto *it = command->child_begin(); it != command->child_end();
180 ++it) {
181
182 if ((*it)->getCommentKind() ==
183 CLANG_UML_LLVM_COMMENT_KIND(ParagraphComment)) {
185 clang::dyn_cast<ParagraphComment>(*it), traits, description);
186 }
187 }
188
189 if (!name.empty()) {
190 if (!cmt.contains("param"))
191 cmt["param"] = inja::json::array();
192
193 inja::json param = inja::json::object();
194 param["name"] = name;
195 param["description"] = util::trim(description);
196 cmt["param"].push_back(std::move(param));
197 }
198}

◆ visit_tparam_command()

void clanguml::common::visitor::comment::clang_visitor::visit_tparam_command ( const clang::comments::TParamCommandComment *  command,
const clang::comments::CommandTraits &  traits,
common::model::comment_t cmt 
)
private

Definition at line 200 of file clang_visitor.cc.

203{
204 using clang::comments::Comment;
205 using clang::comments::ParagraphComment;
206 using clang::comments::TextComment;
207
208 std::string description;
209
210 if (command == nullptr)
211 return;
212
213 const auto name = command->getParamNameAsWritten().str();
214
215 for (const auto *it = command->child_begin(); it != command->child_end();
216 ++it) {
217 if ((*it)->getCommentKind() ==
218 CLANG_UML_LLVM_COMMENT_KIND(ParagraphComment)) {
220 clang::dyn_cast<ParagraphComment>(*it), traits, description);
221 }
222 }
223
224 if (!name.empty()) {
225 if (!cmt.contains("tparam"))
226 cmt["tparam"] = inja::json::array();
227
228 inja::json param = inja::json::object();
229 param["name"] = name;
230 param["description"] = util::trim(description);
231 cmt["tparam"].push_back(std::move(param));
232 }
233}

The documentation for this class was generated from the following files: