12#include "clang/AST/Comment.h"
13#include "clang/AST/CommentCommandTraits.h"
14#include "clang/AST/CommentVisitor.h"
15#include "llvm/ADT/DenseMap.h"
16#include "llvm/ADT/StringRef.h"
22std::string commandMarkerAsString(comments::CommandMarkerKind CommandMarker) {
23 switch (CommandMarker) {
24 case comments::CommandMarkerKind::CMK_At:
26 case comments::CommandMarkerKind::CMK_Backslash:
29 llvm_unreachable(
"Unknown command marker kind");
33 comments::CommandMarkerKind CommandMarker,
35 Out.appendBoldText(commandMarkerAsString(CommandMarker) + Command.str());
38 Out.appendEmphasizedText(Args.str());
44 :
public comments::ConstCommentVisitor<ParagraphToMarkupDocument> {
47 const comments::CommandTraits &Traits)
48 : Out(Out), Traits(Traits) {}
54 for (
const auto *Child = C->child_begin(); Child != C->child_end();
62 StringRef
Text = C->getText();
63 if (LastChunkEndsWithNewline && C->getText().starts_with(
' '))
66 LastChunkEndsWithNewline = C->hasTrailingNewline();
67 Out.appendText(
Text.str() + (LastChunkEndsWithNewline ?
"\n" :
""));
72 if (C->getNumArgs() > 0) {
74 for (
unsigned I = 0; I < C->getNumArgs(); ++I) {
77 ArgText += C->getArgText(I);
80 switch (C->getRenderKind()) {
81 case comments::InlineCommandRenderKind::Monospaced:
82 Out.appendCode(ArgText);
84 case comments::InlineCommandRenderKind::Bold:
85 Out.appendBoldText(ArgText);
87 case comments::InlineCommandRenderKind::Emphasized:
88 Out.appendEmphasizedText(ArgText);
91 commandToMarkup(Out, C->getCommandName(Traits), C->getCommandMarker(),
96 if (C->getCommandName(Traits) ==
"n") {
98 Out.appendText(
" \n");
99 LastChunkEndsWithNewline =
true;
103 commandToMarkup(Out, C->getCommandName(Traits), C->getCommandMarker(),
109 std::string TagText =
"<" + STC->getTagName().str();
111 for (
unsigned I = 0; I < STC->getNumAttrs(); ++I) {
112 const comments::HTMLStartTagComment::Attribute &Attr = STC->getAttr(I);
113 TagText +=
" " + Attr.Name.str() +
"=\"" + Attr.Value.str() +
"\"";
116 if (STC->isSelfClosing())
120 LastChunkEndsWithNewline = STC->hasTrailingNewline();
121 Out.appendText(TagText + (LastChunkEndsWithNewline ?
"\n" :
""));
125 LastChunkEndsWithNewline = ETC->hasTrailingNewline();
126 Out.appendText(
"</" + ETC->getTagName().str() +
">" +
127 (LastChunkEndsWithNewline ?
"\n" :
""));
132 const comments::CommandTraits &Traits;
136 bool LastChunkEndsWithNewline =
true;
140 :
public comments::ConstCommentVisitor<ParagraphToString> {
143 const comments::CommandTraits &Traits)
144 : Out(Out), Traits(Traits) {}
150 for (
const auto *Child = C->child_begin(); Child != C->child_end();
159 Out << commandMarkerAsString(C->getCommandMarker());
160 Out << C->getCommandName(Traits);
161 if (C->getNumArgs() > 0) {
162 for (
unsigned I = 0; I < C->getNumArgs(); ++I)
163 Out <<
" " << C->getArgText(I);
169 Out <<
"<" << STC->getTagName().str();
171 for (
unsigned I = 0; I < STC->getNumAttrs(); ++I) {
172 const comments::HTMLStartTagComment::Attribute &Attr = STC->getAttr(I);
173 Out <<
" " << Attr.Name.str();
174 if (!Attr.Value.str().empty())
175 Out <<
"=\"" << Attr.Value.str() <<
"\"";
178 if (STC->isSelfClosing())
182 Out << (STC->hasTrailingNewline() ?
"\n" :
"");
186 Out <<
"</" << ETC->getTagName().str() <<
">"
187 << (ETC->hasTrailingNewline() ?
"\n" :
"");
191 llvm::raw_string_ostream &Out;
192 const comments::CommandTraits &Traits;
196 :
public comments::ConstCommentVisitor<BlockCommentToMarkupDocument> {
199 const comments::CommandTraits &Traits)
200 : Out(Out), Traits(Traits) {}
204 switch (B->getCommandID()) {
205 case comments::CommandTraits::KCI_arg:
206 case comments::CommandTraits::KCI_li:
211 .visit(B->getParagraph());
218 for (
unsigned I = 0; I < B->getNumArgs(); ++I) {
219 if (!ArgText.empty())
221 ArgText += B->getArgText(I);
223 auto &P = Out.addParagraph();
224 commandToMarkup(P, B->getCommandName(Traits), B->getCommandMarker(),
226 if (B->getParagraph() && !B->getParagraph()->isWhitespace()) {
229 if (!ArgText.empty())
238 commandToMarkup(Out.addParagraph(), VB->getCommandName(Traits),
239 VB->getCommandMarker(),
"");
241 std::string VerbatimText;
243 for (
const auto *LI = VB->child_begin(); LI != VB->child_end(); ++LI) {
244 if (
const auto *Line = cast<comments::VerbatimBlockLineComment>(*LI)) {
245 VerbatimText += Line->getText().str() +
"\n";
249 Out.addCodeBlock(VerbatimText,
"");
251 commandToMarkup(Out.addParagraph(), VB->getCloseName(),
252 VB->getCommandMarker(),
"");
256 auto &P = Out.addParagraph();
257 commandToMarkup(P, VL->getCommandName(Traits), VL->getCommandMarker(),
"");
258 P.appendSpace().appendCode(VL->getText().str(),
true).appendSpace();
262 markup::Document &Out;
263 const comments::CommandTraits &Traits;
264 StringRef CommentEscapeMarker;
268 const comments::BlockCommandComment *B) {
269 switch (B->getCommandID()) {
270 case comments::CommandTraits::KCI_brief: {
271 if (!BriefParagraph) {
272 BriefParagraph = B->getParagraph();
277 case comments::CommandTraits::KCI_return:
278 case comments::CommandTraits::KCI_returns:
279 if (!ReturnParagraph) {
280 ReturnParagraph = B->getParagraph();
284 case comments::CommandTraits::KCI_retval:
285 RetvalParagraphs.push_back(B->getParagraph());
287 case comments::CommandTraits::KCI_warning:
288 WarningParagraphs.push_back(B->getParagraph());
290 case comments::CommandTraits::KCI_note:
291 NoteParagraphs.push_back(B->getParagraph());
299 UnhandledCommands[CommentPartIndex] = B;
303void SymbolDocCommentVisitor::paragraphsToMarkup(
304 markup::Document &Out,
307 if (Paragraphs.empty())
310 for (
const auto *P : Paragraphs) {
322 if (!ReturnParagraph)
328 paragraphsToMarkup(Out, NoteParagraphs);
332 paragraphsToMarkup(Out, WarningParagraphs);
337 if (ParamName.empty())
340 if (
const auto *P = Parameters.lookup(ParamName)) {
346 StringRef ParamName, llvm::raw_string_ostream &Out)
const {
347 if (ParamName.empty())
350 if (
const auto *P = Parameters.lookup(ParamName)) {
356 for (
unsigned I = 0; I < CommentPartIndex; ++I) {
357 if (
const auto *BC = UnhandledCommands.lookup(I)) {
359 }
else if (
const auto *P = FreeParagraphs.lookup(I)) {
367 if (TemplateParamName.empty())
370 if (
const auto *TP = TemplateParameters.lookup(TemplateParamName)) {
376 StringRef TemplateParamName, llvm::raw_string_ostream &Out)
const {
377 if (TemplateParamName.empty())
380 if (
const auto *P = TemplateParameters.lookup(TemplateParamName)) {
void visitHTMLEndTagComment(const comments::HTMLEndTagComment *ETC)
void visitTextComment(const comments::TextComment *C)
void visitHTMLStartTagComment(const comments::HTMLStartTagComment *STC)
void visitParagraphComment(const comments::ParagraphComment *C)
void visitInlineCommandComment(const comments::InlineCommandComment *C)
ParagraphToMarkupDocument(markup::Paragraph &Out, const comments::CommandTraits &Traits)
void visitInlineCommandComment(const comments::InlineCommandComment *C)
void visitHTMLEndTagComment(const comments::HTMLEndTagComment *ETC)
void visitParagraphComment(const comments::ParagraphComment *C)
ParagraphToString(llvm::raw_string_ostream &Out, const comments::CommandTraits &Traits)
void visitTextComment(const comments::TextComment *C)
void visitHTMLStartTagComment(const comments::HTMLStartTagComment *STC)
Represents parts of the markup that can contain strings, like inline code, code block or plain text.
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//