From: Dmitri Gribenko Date: Wed, 1 Aug 2012 22:48:16 +0000 (+0000) Subject: Comment to HTML conversion: refactor. Extracted a class to for FullComment X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2ff84b514e53f4273c7067a5aade680a155a9045;p=clang Comment to HTML conversion: refactor. Extracted a class to for FullComment semantic parts -- this will be reused for comment to XML conversion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@161139 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/libclang/CXComment.cpp b/tools/libclang/CXComment.cpp index ae349c0462..d7859b044a 100644 --- a/tools/libclang/CXComment.cpp +++ b/tools/libclang/CXComment.cpp @@ -396,6 +396,126 @@ public: } }; +/// Separate parts of a FullComment. +struct FullCommentParts { + /// Take a full comment apart and initialize members accordingly. + FullCommentParts(const FullComment *C); + + const BlockContentComment *Brief; + const ParagraphComment *FirstParagraph; + const BlockCommandComment *Returns; + SmallVector Params; + SmallVector TParams; + SmallVector MiscBlocks; +}; + +FullCommentParts::FullCommentParts(const FullComment *C) : + Brief(NULL), FirstParagraph(NULL), Returns(NULL) { + for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); + I != E; ++I) { + const Comment *Child = *I; + if (!Child) + continue; + switch (Child->getCommentKind()) { + case Comment::NoCommentKind: + continue; + + case Comment::ParagraphCommentKind: { + const ParagraphComment *PC = cast(Child); + if (PC->isWhitespace()) + break; + if (!FirstParagraph) + FirstParagraph = PC; + + MiscBlocks.push_back(PC); + break; + } + + case Comment::BlockCommandCommentKind: { + const BlockCommandComment *BCC = cast(Child); + StringRef CommandName = BCC->getCommandName(); + if (!Brief && (CommandName == "brief" || CommandName == "short")) { + Brief = BCC; + break; + } + if (!Returns && (CommandName == "returns" || CommandName == "return")) { + Returns = BCC; + break; + } + MiscBlocks.push_back(BCC); + break; + } + + case Comment::ParamCommandCommentKind: { + const ParamCommandComment *PCC = cast(Child); + if (!PCC->hasParamName()) + break; + + if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph()) + break; + + Params.push_back(PCC); + break; + } + + case Comment::TParamCommandCommentKind: { + const TParamCommandComment *TPCC = cast(Child); + if (!TPCC->hasParamName()) + break; + + if (!TPCC->hasNonWhitespaceParagraph()) + break; + + TParams.push_back(TPCC); + break; + } + + case Comment::VerbatimBlockCommentKind: + case Comment::VerbatimLineCommentKind: + MiscBlocks.push_back(cast(Child)); + break; + + case Comment::TextCommentKind: + case Comment::InlineCommandCommentKind: + case Comment::HTMLStartTagCommentKind: + case Comment::HTMLEndTagCommentKind: + case Comment::VerbatimBlockLineCommentKind: + case Comment::FullCommentKind: + llvm_unreachable("AST node of this kind can't be a child of " + "a FullComment"); + } + } + + // Sort params in order they are declared in the function prototype. + // Unresolved parameters are put at the end of the list in the same order + // they were seen in the comment. + std::stable_sort(Params.begin(), Params.end(), + ParamCommandCommentCompareIndex()); + + std::stable_sort(TParams.begin(), TParams.end(), + TParamCommandCommentComparePosition()); +} + +void PrintHTMLStartTagComment(const HTMLStartTagComment *C, + llvm::raw_svector_ostream &Result) { + Result << "<" << C->getTagName(); + + if (C->getNumAttrs() != 0) { + for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) { + Result << " "; + const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); + Result << Attr.Name; + if (!Attr.Value.empty()) + Result << "=\"" << Attr.Value << "\""; + } + } + + if (!C->isSelfClosing()) + Result << ">"; + else + Result << "/>"; +} + class CommentASTToHTMLConverter : public ConstCommentVisitor { public: @@ -479,22 +599,7 @@ void CommentASTToHTMLConverter::visitInlineCommandComment( void CommentASTToHTMLConverter::visitHTMLStartTagComment( const HTMLStartTagComment *C) { - Result << "<" << C->getTagName(); - - if (C->getNumAttrs() != 0) { - for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) { - Result << " "; - const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); - Result << Attr.Name; - if (!Attr.Value.empty()) - Result << "=\"" << Attr.Value << "\""; - } - } - - if (!C->isSelfClosing()) - Result << ">"; - else - Result << "/>"; + PrintHTMLStartTagComment(C, Result); } void CommentASTToHTMLConverter::visitHTMLEndTagComment( @@ -616,131 +721,41 @@ void CommentASTToHTMLConverter::visitVerbatimLineComment( } void CommentASTToHTMLConverter::visitFullComment(const FullComment *C) { - const BlockContentComment *Brief = NULL; - const ParagraphComment *FirstParagraph = NULL; - const BlockCommandComment *Returns = NULL; - SmallVector Params; - SmallVector TParams; - SmallVector MiscBlocks; - - // Extract various blocks into separate variables and vectors above. - for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); - I != E; ++I) { - const Comment *Child = *I; - if (!Child) - continue; - switch (Child->getCommentKind()) { - case Comment::NoCommentKind: - continue; - - case Comment::ParagraphCommentKind: { - const ParagraphComment *PC = cast(Child); - if (PC->isWhitespace()) - break; - if (!FirstParagraph) - FirstParagraph = PC; - - MiscBlocks.push_back(PC); - break; - } - - case Comment::BlockCommandCommentKind: { - const BlockCommandComment *BCC = cast(Child); - StringRef CommandName = BCC->getCommandName(); - if (!Brief && (CommandName == "brief" || CommandName == "short")) { - Brief = BCC; - break; - } - if (!Returns && (CommandName == "returns" || CommandName == "return")) { - Returns = BCC; - break; - } - MiscBlocks.push_back(BCC); - break; - } - - case Comment::ParamCommandCommentKind: { - const ParamCommandComment *PCC = cast(Child); - if (!PCC->hasParamName()) - break; - - if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph()) - break; - - Params.push_back(PCC); - break; - } - - case Comment::TParamCommandCommentKind: { - const TParamCommandComment *TPCC = cast(Child); - if (!TPCC->hasParamName()) - break; - - if (!TPCC->hasNonWhitespaceParagraph()) - break; - - TParams.push_back(TPCC); - break; - } - - case Comment::VerbatimBlockCommentKind: - case Comment::VerbatimLineCommentKind: - MiscBlocks.push_back(cast(Child)); - break; - - case Comment::TextCommentKind: - case Comment::InlineCommandCommentKind: - case Comment::HTMLStartTagCommentKind: - case Comment::HTMLEndTagCommentKind: - case Comment::VerbatimBlockLineCommentKind: - case Comment::FullCommentKind: - llvm_unreachable("AST node of this kind can't be a child of " - "a FullComment"); - } - } - - // Sort params in order they are declared in the function prototype. - // Unresolved parameters are put at the end of the list in the same order - // they were seen in the comment. - std::stable_sort(Params.begin(), Params.end(), - ParamCommandCommentCompareIndex()); - - std::stable_sort(TParams.begin(), TParams.end(), - TParamCommandCommentComparePosition()); + FullCommentParts Parts(C); bool FirstParagraphIsBrief = false; - if (Brief) - visit(Brief); - else if (FirstParagraph) { + if (Parts.Brief) + visit(Parts.Brief); + else if (Parts.FirstParagraph) { Result << "

"; - visitNonStandaloneParagraphComment(FirstParagraph); + visitNonStandaloneParagraphComment(Parts.FirstParagraph); Result << "

"; FirstParagraphIsBrief = true; } - for (unsigned i = 0, e = MiscBlocks.size(); i != e; ++i) { - const Comment *C = MiscBlocks[i]; - if (FirstParagraphIsBrief && C == FirstParagraph) + for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) { + const Comment *C = Parts.MiscBlocks[i]; + if (FirstParagraphIsBrief && C == Parts.FirstParagraph) continue; visit(C); } - if (TParams.size() != 0) { + if (Parts.TParams.size() != 0) { Result << "
"; - for (unsigned i = 0, e = TParams.size(); i != e; ++i) - visit(TParams[i]); + for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i) + visit(Parts.TParams[i]); Result << "
"; } - if (Params.size() != 0) { + if (Parts.Params.size() != 0) { Result << "
"; - for (unsigned i = 0, e = Params.size(); i != e; ++i) - visit(Params[i]); + for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i) + visit(Parts.Params[i]); Result << "
"; } - if (Returns) - visit(Returns); + if (Parts.Returns) + visit(Parts.Returns); Result.flush(); }