diff options
author | Dmitri Gribenko <gribozavr@gmail.com> | 2012-07-21 01:47:43 +0000 |
---|---|---|
committer | Dmitri Gribenko <gribozavr@gmail.com> | 2012-07-21 01:47:43 +0000 |
commit | 3e63d332baf0d3b8a5c0b7c2dac2ae85615b1d47 (patch) | |
tree | df70d3956695d9b917e345d4209c141077b144b4 | |
parent | d256f8673bf2499f57e0f40aab30ff243d576c17 (diff) |
Comment to HTML conversion: add more CSS classes to identify function arguments
by index. This is useful if the user does not document all arguments, and we
can't find a particular argument by index via :nth-of-type() CSS selector.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160595 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang-c/Index.h | 8 | ||||
-rw-r--r-- | test/Index/annotate-comments.cpp | 12 | ||||
-rw-r--r-- | tools/libclang/CXComment.cpp | 133 |
3 files changed, 78 insertions, 75 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index d95f010a6f..93a522457e 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -3563,8 +3563,12 @@ CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment); * \li "para-returns" for \\returns paragraph and equivalent commands; * \li "word-returns" for the "Returns" word in \\returns paragraph. * - * Argument list is rendered as \<dl\> list with arguments sorted in function - * prototype order. + * Function argument documentation is rendered as a \<dl\> list with arguments + * sorted in function prototype order. CSS classes used: + * \li "param-name-index-NUMBER" for parameter name (\<dt\>); + * \li "param-descr-index-NUMBER" for parameter description (\<dd\>); + * \li "param-name-index-invalid" and "param-descr-index-invalid" are used if + * parameter index is invalid. * * \param Comment a \c CXComment_FullComment AST node. * diff --git a/test/Index/annotate-comments.cpp b/test/Index/annotate-comments.cpp index 9ed1c30c49..872a9fa424 100644 --- a/test/Index/annotate-comments.cpp +++ b/test/Index/annotate-comments.cpp @@ -483,7 +483,7 @@ void comment_to_html_conversion_22(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[returns] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Ccc.]))))] -// CHECK: annotate-comments.cpp:271:6: FunctionDecl=comment_to_html_conversion_11:{{.*}} FullCommentAsHTML=[<dl><dt>x1</dt><dd> Aaa.</dd></dl>] +// CHECK: annotate-comments.cpp:271:6: FunctionDecl=comment_to_html_conversion_11:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd></dl>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -491,7 +491,7 @@ void comment_to_html_conversion_22(); // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[x1] ParamIndex=0 // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.]))))] -// CHECK: annotate-comments.cpp:274:6: FunctionDecl=comment_to_html_conversion_12:{{.*}} FullCommentAsHTML=[<dl><dt>zzz</dt><dd> Aaa.</dd></dl>] +// CHECK: annotate-comments.cpp:274:6: FunctionDecl=comment_to_html_conversion_12:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa.</dd></dl>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -499,7 +499,7 @@ void comment_to_html_conversion_22(); // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[zzz] ParamIndex=Invalid // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.]))))] -// CHECK: annotate-comments.cpp:278:6: FunctionDecl=comment_to_html_conversion_13:{{.*}} FullCommentAsHTML=[<dl><dt>x1</dt><dd> Aaa.</dd><dt>x2</dt><dd> Bbb. </dd></dl>] +// CHECK: annotate-comments.cpp:278:6: FunctionDecl=comment_to_html_conversion_13:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd></dl>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -511,7 +511,7 @@ void comment_to_html_conversion_22(); // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[x1] ParamIndex=0 // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.]))))] -// CHECK: annotate-comments.cpp:283:6: FunctionDecl=comment_to_html_conversion_14:{{.*}} FullCommentAsHTML=[<dl><dt>x1</dt><dd> Aaa.</dd><dt>x2</dt><dd> Bbb. </dd><dt>zzz</dt><dd> Aaa. </dd></dl>] +// CHECK: annotate-comments.cpp:283:6: FunctionDecl=comment_to_html_conversion_14:{{.*}} FullCommentAsHTML=[<dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Aaa.</dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Bbb. </dd><dt class="param-name-index-invalid">zzz</dt><dd class="param-descr-index-invalid"> Aaa. </dd></dl>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -527,7 +527,7 @@ void comment_to_html_conversion_22(); // CHECK-NEXT: (CXComment_ParamCommand in implicitly ParamName=[x1] ParamIndex=0 // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Aaa.]))))] -// CHECK: annotate-comments.cpp:292:6: FunctionDecl=comment_to_html_conversion_15:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><dl><dt>x1</dt><dd> Ccc. </dd><dt>x2</dt><dd> Ddd. </dd></dl><p class="para-returns"><span class="word-returns">Returns</span> Eee.</p>] +// CHECK: annotate-comments.cpp:292:6: FunctionDecl=comment_to_html_conversion_15:{{.*}} FullCommentAsHTML=[<p class="para-brief"> Aaa.</p><p> Bbb.</p><dl><dt class="param-name-index-0">x1</dt><dd class="param-descr-index-0"> Ccc. </dd><dt class="param-name-index-1">x2</dt><dd class="param-descr-index-1"> Ddd. </dd></dl><p class="para-returns"><span class="word-returns">Returns</span> Eee.</p>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph IsWhitespace @@ -550,7 +550,7 @@ void comment_to_html_conversion_22(); // CHECK-NEXT: (CXComment_BlockCommand CommandName=[returns] // CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Text Text=[ Eee.]))))] -// CHECK: annotate-comments.cpp:295:6: FunctionDecl=comment_to_html_conversion_16:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <br><a href="http://example.com/ ">Aaa</a></p>] +// CHECK: annotate-comments.cpp:295:6: FunctionDecl=comment_to_html_conversion_16:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <br><a href="http://example.com/">Aaa</a></p>] // CHECK-NEXT: CommentAST=[ // CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_Paragraph diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp index 8d01a4192f..b0ed9bcc00 100644 --- a/tools/libclang/CXComment.cpp +++ b/tools/libclang/CXComment.cpp @@ -18,6 +18,7 @@ #include "clang/AST/CommentVisitor.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace clang; using namespace clang::cxstring; @@ -304,7 +305,8 @@ public: class CommentASTToHTMLConverter : public ConstCommentVisitor<CommentASTToHTMLConverter> { public: - CommentASTToHTMLConverter() { } + /// \param Str accumulator for HTML. + CommentASTToHTMLConverter(SmallVectorImpl<char> &Str) : Result(Str) { } // Inline content. void visitTextComment(const TextComment *C); @@ -330,13 +332,9 @@ public: void appendToResultWithHTMLEscaping(StringRef S); - StringRef getAsHTML() const { - return Result; - } - private: - /// Accumulator for converted HTML. - std::string Result; + /// Output stream for HTML. + llvm::raw_svector_ostream Result; }; } // end unnamed namespace @@ -355,64 +353,50 @@ void CommentASTToHTMLConverter::visitInlineCommandComment( if (CommandName == "b") { if (!HasArg0) return; - Result += "<b>"; - Result += Arg0; - Result += "</b>"; + Result << "<b>" << Arg0 << "</b>"; return; } if (CommandName == "c" || CommandName == "p") { if (!HasArg0) return; - Result += "<tt>"; - Result += Arg0; - Result += "</tt>"; + Result << "<tt>" << Arg0 << "</tt>"; return; } if (CommandName == "a" || CommandName == "e" || CommandName == "em") { if (!HasArg0) return; - Result += "<em>"; - Result += Arg0; - Result += "</em>"; + Result << "<em>" << Arg0 << "</em>"; return; } // We don't recognize this command, so just print its arguments. - for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) { - Result += C->getArgText(i); - Result += " "; - } + for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) + Result << C->getArgText(i) << " "; } void CommentASTToHTMLConverter::visitHTMLStartTagComment( const HTMLStartTagComment *C) { - Result += "<"; - Result += C->getTagName(); + Result << "<" << C->getTagName(); if (C->getNumAttrs() != 0) { for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) { - Result += " "; + Result << " "; const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); - Result += Attr.Name; - if (!Attr.Value.empty()) { - Result += "=\""; - Result += Attr.Value; - Result += " \""; - } + Result << Attr.Name; + if (!Attr.Value.empty()) + Result << "=\"" << Attr.Value << "\""; } } if (!C->isSelfClosing()) - Result += ">"; + Result << ">"; else - Result += "/>"; + Result << "/>"; } void CommentASTToHTMLConverter::visitHTMLEndTagComment( const HTMLEndTagComment *C) { - Result += "</"; - Result += C->getTagName(); - Result += ">"; + Result << "</" << C->getTagName() << ">"; } void CommentASTToHTMLConverter::visitParagraphComment( @@ -420,28 +404,28 @@ void CommentASTToHTMLConverter::visitParagraphComment( if (C->isWhitespace()) return; - Result += "<p>"; + Result << "<p>"; for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); I != E; ++I) { visit(*I); } - Result += "</p>"; + Result << "</p>"; } void CommentASTToHTMLConverter::visitBlockCommandComment( const BlockCommandComment *C) { StringRef CommandName = C->getCommandName(); if (CommandName == "brief" || CommandName == "short") { - Result += "<p class=\"para-brief\">"; + Result << "<p class=\"para-brief\">"; visitNonStandaloneParagraphComment(C->getParagraph()); - Result += "</p>"; + Result << "</p>"; return; } if (CommandName == "returns" || CommandName == "return") { - Result += "<p class=\"para-returns\">"; - Result += "<span class=\"word-returns\">Returns</span> "; + Result << "<p class=\"para-returns\">" + "<span class=\"word-returns\">Returns</span> "; visitNonStandaloneParagraphComment(C->getParagraph()); - Result += "</p>"; + Result << "</p>"; return; } // We don't know anything about this command. Just render the paragraph. @@ -450,12 +434,24 @@ void CommentASTToHTMLConverter::visitBlockCommandComment( void CommentASTToHTMLConverter::visitParamCommandComment( const ParamCommandComment *C) { - Result += "<dt>"; - Result += C->getParamName(); - Result += "</dt>"; - Result += "<dd>"; + if (C->isParamIndexValid()) { + Result << "<dt class=\"param-name-index-" + << C->getParamIndex() + << "\">"; + } else + Result << "<dt class=\"param-name-index-invalid\">"; + + Result << C->getParamName() << "</dt>"; + + if (C->isParamIndexValid()) { + Result << "<dd class=\"param-descr-index-" + << C->getParamIndex() + << "\">"; + } else + Result << "<dd class=\"param-descr-index-invalid\">"; + visitNonStandaloneParagraphComment(C->getParagraph()); - Result += "</dd>"; + Result << "</dd>"; } void CommentASTToHTMLConverter::visitVerbatimBlockComment( @@ -464,13 +460,13 @@ void CommentASTToHTMLConverter::visitVerbatimBlockComment( if (NumLines == 0) return; - Result += "<pre>"; + Result << "<pre>"; for (unsigned i = 0; i != NumLines; ++i) { appendToResultWithHTMLEscaping(C->getText(i)); if (i + 1 != NumLines) - Result.append("\n"); + Result << '\n'; } - Result += "</pre>"; + Result << "</pre>"; } void CommentASTToHTMLConverter::visitVerbatimBlockLineComment( @@ -480,9 +476,9 @@ void CommentASTToHTMLConverter::visitVerbatimBlockLineComment( void CommentASTToHTMLConverter::visitVerbatimLineComment( const VerbatimLineComment *C) { - Result += "<pre>"; + Result << "<pre>"; appendToResultWithHTMLEscaping(C->getText()); - Result += "</pre>"; + Result << "</pre>"; } void CommentASTToHTMLConverter::visitFullComment(const FullComment *C) { @@ -566,9 +562,9 @@ void CommentASTToHTMLConverter::visitFullComment(const FullComment *C) { if (Brief) visit(Brief); else if (FirstParagraph) { - Result += "<p class=\"para-brief\">"; + Result << "<p class=\"para-brief\">"; visitNonStandaloneParagraphComment(FirstParagraph); - Result += "</p>"; + Result << "</p>"; FirstParagraphIsBrief = true; } @@ -580,14 +576,16 @@ void CommentASTToHTMLConverter::visitFullComment(const FullComment *C) { } if (Params.size() != 0) { - Result += "<dl>"; + Result << "<dl>"; for (unsigned i = 0, e = Params.size(); i != e; ++i) visit(Params[i]); - Result += "</dl>"; + Result << "</dl>"; } if (Returns) visit(Returns); + + Result.flush(); } void CommentASTToHTMLConverter::visitNonStandaloneParagraphComment( @@ -602,30 +600,29 @@ void CommentASTToHTMLConverter::visitNonStandaloneParagraphComment( } void CommentASTToHTMLConverter::appendToResultWithHTMLEscaping(StringRef S) { - Result.reserve(Result.size() + S.size()); for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) { const char C = *I; switch (C) { case '&': - Result.append("&"); + Result << "&"; break; case '<': - Result.append("<"); + Result << "<"; break; case '>': - Result.append(">"); + Result << ">"; break; case '"': - Result.append("""); + Result << """; break; case '\'': - Result.append("'"); + Result << "'"; break; case '/': - Result.append("/"); + Result << "/"; break; default: - Result.push_back(C); + Result << C; break; } } @@ -638,9 +635,10 @@ CXString clang_HTMLTagComment_getAsString(CXComment CXC) { if (!HTC) return createCXString((const char *) 0); - CommentASTToHTMLConverter Converter; + SmallString<128> HTML; + CommentASTToHTMLConverter Converter(HTML); Converter.visit(HTC); - return createCXString(Converter.getAsHTML()); + return createCXString(HTML.str(), /* DupString = */ true); } CXString clang_FullComment_getAsHTML(CXComment CXC) { @@ -648,9 +646,10 @@ CXString clang_FullComment_getAsHTML(CXComment CXC) { if (!FC) return createCXString((const char *) 0); - CommentASTToHTMLConverter Converter; + SmallString<1024> HTML; + CommentASTToHTMLConverter Converter(HTML); Converter.visit(FC); - return createCXString(Converter.getAsHTML()); + return createCXString(HTML.str(), /* DupString = */ true); } } // end extern "C" |