Comment to HTML conversion: refactor. Extracted a class to for FullComment
semantic parts -- this will be reused for comment to XML conversion. llvm-svn: 161139
This commit is contained in:
parent
2db6b65330
commit
3a770d0fe4
|
@ -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<const ParamCommandComment *, 8> Params;
|
||||
SmallVector<const TParamCommandComment *, 4> TParams;
|
||||
SmallVector<const BlockContentComment *, 8> 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<ParagraphComment>(Child);
|
||||
if (PC->isWhitespace())
|
||||
break;
|
||||
if (!FirstParagraph)
|
||||
FirstParagraph = PC;
|
||||
|
||||
MiscBlocks.push_back(PC);
|
||||
break;
|
||||
}
|
||||
|
||||
case Comment::BlockCommandCommentKind: {
|
||||
const BlockCommandComment *BCC = cast<BlockCommandComment>(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<ParamCommandComment>(Child);
|
||||
if (!PCC->hasParamName())
|
||||
break;
|
||||
|
||||
if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph())
|
||||
break;
|
||||
|
||||
Params.push_back(PCC);
|
||||
break;
|
||||
}
|
||||
|
||||
case Comment::TParamCommandCommentKind: {
|
||||
const TParamCommandComment *TPCC = cast<TParamCommandComment>(Child);
|
||||
if (!TPCC->hasParamName())
|
||||
break;
|
||||
|
||||
if (!TPCC->hasNonWhitespaceParagraph())
|
||||
break;
|
||||
|
||||
TParams.push_back(TPCC);
|
||||
break;
|
||||
}
|
||||
|
||||
case Comment::VerbatimBlockCommentKind:
|
||||
case Comment::VerbatimLineCommentKind:
|
||||
MiscBlocks.push_back(cast<BlockCommandComment>(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<CommentASTToHTMLConverter> {
|
||||
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<const ParamCommandComment *, 8> Params;
|
||||
SmallVector<const TParamCommandComment *, 4> TParams;
|
||||
SmallVector<const BlockContentComment *, 8> 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<ParagraphComment>(Child);
|
||||
if (PC->isWhitespace())
|
||||
break;
|
||||
if (!FirstParagraph)
|
||||
FirstParagraph = PC;
|
||||
|
||||
MiscBlocks.push_back(PC);
|
||||
break;
|
||||
}
|
||||
|
||||
case Comment::BlockCommandCommentKind: {
|
||||
const BlockCommandComment *BCC = cast<BlockCommandComment>(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<ParamCommandComment>(Child);
|
||||
if (!PCC->hasParamName())
|
||||
break;
|
||||
|
||||
if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph())
|
||||
break;
|
||||
|
||||
Params.push_back(PCC);
|
||||
break;
|
||||
}
|
||||
|
||||
case Comment::TParamCommandCommentKind: {
|
||||
const TParamCommandComment *TPCC = cast<TParamCommandComment>(Child);
|
||||
if (!TPCC->hasParamName())
|
||||
break;
|
||||
|
||||
if (!TPCC->hasNonWhitespaceParagraph())
|
||||
break;
|
||||
|
||||
TParams.push_back(TPCC);
|
||||
break;
|
||||
}
|
||||
|
||||
case Comment::VerbatimBlockCommentKind:
|
||||
case Comment::VerbatimLineCommentKind:
|
||||
MiscBlocks.push_back(cast<BlockCommandComment>(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 << "<p class=\"para-brief\">";
|
||||
visitNonStandaloneParagraphComment(FirstParagraph);
|
||||
visitNonStandaloneParagraphComment(Parts.FirstParagraph);
|
||||
Result << "</p>";
|
||||
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 << "<dl>";
|
||||
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 << "</dl>";
|
||||
}
|
||||
|
||||
if (Params.size() != 0) {
|
||||
if (Parts.Params.size() != 0) {
|
||||
Result << "<dl>";
|
||||
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 << "</dl>";
|
||||
}
|
||||
|
||||
if (Returns)
|
||||
visit(Returns);
|
||||
if (Parts.Returns)
|
||||
visit(Parts.Returns);
|
||||
|
||||
Result.flush();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue