Comment AST: add InlineContentComment::RenderKind to specify a default

rendering mode for clients that don't want to interpret Doxygen commands.

Also add a libclang API to query this information.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160633 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dmitri Gribenko 2012-07-23 16:43:01 +00:00
Родитель 1cc9be04bd
Коммит 2d66a5016d
9 изменённых файлов: 174 добавлений и 40 удалений

Просмотреть файл

@ -3307,6 +3307,33 @@ enum CXCommentKind {
CXComment_FullComment = 11 CXComment_FullComment = 11
}; };
/**
* \brief The most appropriate rendering mode for an inline command, chosen on
* command semantics in Doxygen.
*/
enum CXCommentInlineCommandRenderKind {
/**
* \brief Command argument should be rendered in a normal font.
*/
CXCommentInlineCommandRenderKind_Normal,
/**
* \brief Command argument should be rendered in a bold font.
*/
CXCommentInlineCommandRenderKind_Bold,
/**
* \brief Command argument should be rendered in a monospaced font.
*/
CXCommentInlineCommandRenderKind_Monospaced,
/**
* \brief Command argument should be rendered emphasized (typically italic
* font).
*/
CXCommentInlineCommandRenderKind_Emphasized
};
/** /**
* \brief Describes parameter passing direction for \\param or \\arg command. * \brief Describes parameter passing direction for \\param or \\arg command.
*/ */
@ -3385,6 +3412,15 @@ CINDEX_LINKAGE CXString clang_TextComment_getText(CXComment Comment);
CINDEX_LINKAGE CINDEX_LINKAGE
CXString clang_InlineCommandComment_getCommandName(CXComment Comment); CXString clang_InlineCommandComment_getCommandName(CXComment Comment);
/**
* \param Comment a \c CXComment_InlineCommand AST node.
*
* \returns the most appropriate rendering mode, chosen on command
* semantics in Doxygen.
*/
CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind
clang_InlineCommandComment_getRenderKind(CXComment Comment);
/** /**
* \param Comment a \c CXComment_InlineCommand AST node. * \param Comment a \c CXComment_InlineCommand AST node.
* *

Просмотреть файл

@ -63,6 +63,15 @@ protected:
}; };
enum { NumTextCommentBits = NumInlineContentCommentBits + 2 }; enum { NumTextCommentBits = NumInlineContentCommentBits + 2 };
class InlineCommandCommentBitfields {
friend class InlineCommandComment;
unsigned : NumInlineContentCommentBits;
unsigned RenderKind : 2;
};
enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 1 };
class HTMLStartTagCommentBitfields { class HTMLStartTagCommentBitfields {
friend class HTMLStartTagComment; friend class HTMLStartTagComment;
@ -104,6 +113,7 @@ protected:
CommentBitfields CommentBits; CommentBitfields CommentBits;
InlineContentCommentBitfields InlineContentCommentBits; InlineContentCommentBitfields InlineContentCommentBits;
TextCommentBitfields TextCommentBits; TextCommentBitfields TextCommentBits;
InlineCommandCommentBitfields InlineCommandCommentBits;
HTMLStartTagCommentBitfields HTMLStartTagCommentBits; HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
ParagraphCommentBitfields ParagraphCommentBits; ParagraphCommentBitfields ParagraphCommentBits;
ParamCommandCommentBitfields ParamCommandCommentBits; ParamCommandCommentBitfields ParamCommandCommentBits;
@ -248,6 +258,15 @@ public:
Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { } Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
}; };
/// The most appropriate rendering mode for this command, chosen on command
/// semantics in Doxygen.
enum RenderKind {
RenderNormal,
RenderBold,
RenderMonospaced,
RenderEmphasized
};
protected: protected:
/// Command name. /// Command name.
StringRef Name; StringRef Name;
@ -259,10 +278,12 @@ public:
InlineCommandComment(SourceLocation LocBegin, InlineCommandComment(SourceLocation LocBegin,
SourceLocation LocEnd, SourceLocation LocEnd,
StringRef Name, StringRef Name,
RenderKind RK,
llvm::ArrayRef<Argument> Args) : llvm::ArrayRef<Argument> Args) :
InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd), InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
Name(Name), Args(Args) Name(Name), Args(Args) {
{ } InlineCommandCommentBits.RenderKind = RK;
}
static bool classof(const Comment *C) { static bool classof(const Comment *C) {
return C->getCommentKind() == InlineCommandCommentKind; return C->getCommentKind() == InlineCommandCommentKind;
@ -283,6 +304,10 @@ public:
getLocEnd()); getLocEnd());
} }
RenderKind getRenderKind() const {
return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind);
}
unsigned getNumArgs() const { unsigned getNumArgs() const {
return Args.size(); return Args.size();
} }

Просмотреть файл

@ -155,7 +155,10 @@ public:
bool isParamCommand(StringRef Name); bool isParamCommand(StringRef Name);
unsigned getBlockCommandNumArgs(StringRef Name); unsigned getBlockCommandNumArgs(StringRef Name);
bool isInlineCommand(StringRef Name); bool isInlineCommand(StringRef Name) const;
InlineCommandComment::RenderKind
getInlineCommandRenderKind(StringRef Name) const;
bool isHTMLEndTagOptional(StringRef Name); bool isHTMLEndTagOptional(StringRef Name);
bool isHTMLEndTagForbidden(StringRef Name); bool isHTMLEndTagForbidden(StringRef Name);

Просмотреть файл

@ -107,6 +107,21 @@ void CommentDumper::visitInlineCommandComment(const InlineCommandComment *C) {
dumpComment(C); dumpComment(C);
OS << " Name=\"" << C->getCommandName() << "\""; OS << " Name=\"" << C->getCommandName() << "\"";
switch (C->getRenderKind()) {
case InlineCommandComment::RenderNormal:
OS << " RenderNormal";
break;
case InlineCommandComment::RenderBold:
OS << " RenderBold";
break;
case InlineCommandComment::RenderMonospaced:
OS << " RenderMonospaced";
break;
case InlineCommandComment::RenderEmphasized:
OS << " RenderEmphasized";
break;
}
for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
} }

Просмотреть файл

@ -202,10 +202,12 @@ InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin,
SourceLocation CommandLocEnd, SourceLocation CommandLocEnd,
StringRef CommandName) { StringRef CommandName) {
ArrayRef<InlineCommandComment::Argument> Args; ArrayRef<InlineCommandComment::Argument> Args;
return new (Allocator) InlineCommandComment(CommandLocBegin, return new (Allocator) InlineCommandComment(
CommandLocEnd, CommandLocBegin,
CommandName, CommandLocEnd,
Args); CommandName,
getInlineCommandRenderKind(CommandName),
Args);
} }
InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin, InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin,
@ -219,17 +221,22 @@ InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin,
ArgLocEnd), ArgLocEnd),
Arg); Arg);
return new (Allocator) InlineCommandComment(CommandLocBegin, return new (Allocator) InlineCommandComment(
CommandLocEnd, CommandLocBegin,
CommandName, CommandLocEnd,
llvm::makeArrayRef(A, 1)); CommandName,
getInlineCommandRenderKind(CommandName),
llvm::makeArrayRef(A, 1));
} }
InlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin, InlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin,
SourceLocation LocEnd, SourceLocation LocEnd,
StringRef Name) { StringRef Name) {
ArrayRef<InlineCommandComment::Argument> Args; ArrayRef<InlineCommandComment::Argument> Args;
return new (Allocator) InlineCommandComment(LocBegin, LocEnd, Name, Args); return new (Allocator) InlineCommandComment(
LocBegin, LocEnd, Name,
InlineCommandComment::RenderNormal,
Args);
} }
TextComment *Sema::actOnText(SourceLocation LocBegin, TextComment *Sema::actOnText(SourceLocation LocBegin,
@ -445,7 +452,7 @@ unsigned Sema::getBlockCommandNumArgs(StringRef Name) {
.Default(0); .Default(0);
} }
bool Sema::isInlineCommand(StringRef Name) { bool Sema::isInlineCommand(StringRef Name) const {
return llvm::StringSwitch<bool>(Name) return llvm::StringSwitch<bool>(Name)
.Case("b", true) .Case("b", true)
.Cases("c", "p", true) .Cases("c", "p", true)
@ -453,6 +460,17 @@ bool Sema::isInlineCommand(StringRef Name) {
.Default(false); .Default(false);
} }
InlineCommandComment::RenderKind
Sema::getInlineCommandRenderKind(StringRef Name) const {
assert(isInlineCommand(Name));
return llvm::StringSwitch<InlineCommandComment::RenderKind>(Name)
.Case("b", InlineCommandComment::RenderBold)
.Cases("c", "p", InlineCommandComment::RenderMonospaced)
.Cases("a", "e", "em", InlineCommandComment::RenderEmphasized)
.Default(InlineCommandComment::RenderNormal);
}
bool Sema::isHTMLEndTagOptional(StringRef Name) { bool Sema::isHTMLEndTagOptional(StringRef Name) {
return llvm::StringSwitch<bool>(Name) return llvm::StringSwitch<bool>(Name)
.Case("p", true) .Case("p", true)

Просмотреть файл

@ -572,25 +572,25 @@ void comment_to_html_conversion_22();
// CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_FullComment
// CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Paragraph
// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)
// CHECK-NEXT: (CXComment_InlineCommand CommandName=[b] Arg[0]=Aaa)))] // CHECK-NEXT: (CXComment_InlineCommand CommandName=[b] RenderBold Arg[0]=Aaa)))]
// CHECK: annotate-comments.cpp:307:6: FunctionDecl=comment_to_html_conversion_19:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <tt>Aaa</tt> <tt>Bbb</tt></p>] // CHECK: annotate-comments.cpp:307:6: FunctionDecl=comment_to_html_conversion_19:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <tt>Aaa</tt> <tt>Bbb</tt></p>]
// CHECK-NEXT: CommentAST=[ // CHECK-NEXT: CommentAST=[
// CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_FullComment
// CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Paragraph
// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)
// CHECK-NEXT: (CXComment_InlineCommand CommandName=[c] Arg[0]=Aaa) // CHECK-NEXT: (CXComment_InlineCommand CommandName=[c] RenderMonospaced Arg[0]=Aaa)
// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)
// CHECK-NEXT: (CXComment_InlineCommand CommandName=[p] Arg[0]=Bbb)))] // CHECK-NEXT: (CXComment_InlineCommand CommandName=[p] RenderMonospaced Arg[0]=Bbb)))]
// CHECK: annotate-comments.cpp:310:6: FunctionDecl=comment_to_html_conversion_20:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>Aaa</em> <em>Bbb</em> <em>Ccc</em></p>] // CHECK: annotate-comments.cpp:310:6: FunctionDecl=comment_to_html_conversion_20:{{.*}} FullCommentAsHTML=[<p class="para-brief"> <em>Aaa</em> <em>Bbb</em> <em>Ccc</em></p>]
// CHECK-NEXT: CommentAST=[ // CHECK-NEXT: CommentAST=[
// CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_FullComment
// CHECK-NEXT: (CXComment_Paragraph // CHECK-NEXT: (CXComment_Paragraph
// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)
// CHECK-NEXT: (CXComment_InlineCommand CommandName=[a] Arg[0]=Aaa) // CHECK-NEXT: (CXComment_InlineCommand CommandName=[a] RenderEmphasized Arg[0]=Aaa)
// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)
// CHECK-NEXT: (CXComment_InlineCommand CommandName=[e] Arg[0]=Bbb) // CHECK-NEXT: (CXComment_InlineCommand CommandName=[e] RenderEmphasized Arg[0]=Bbb)
// CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace) // CHECK-NEXT: (CXComment_Text Text=[ ] IsWhitespace)
// CHECK-NEXT: (CXComment_InlineCommand CommandName=[em] Arg[0]=Ccc)))] // CHECK-NEXT: (CXComment_InlineCommand CommandName=[em] RenderEmphasized Arg[0]=Ccc)))]
// CHECK: annotate-comments.cpp:313:6: FunctionDecl=comment_to_html_conversion_21:{{.*}} FullCommentAsHTML=[<p class="para-brief"> \ @ &amp; $ # &lt; &gt; % &quot; . ::</p>] // CHECK: annotate-comments.cpp:313:6: FunctionDecl=comment_to_html_conversion_21:{{.*}} FullCommentAsHTML=[<p class="para-brief"> \ @ &amp; $ # &lt; &gt; % &quot; . ::</p>]
// CHECK-NEXT: CommentAST=[ // CHECK-NEXT: CommentAST=[
// CHECK-NEXT: (CXComment_FullComment // CHECK-NEXT: (CXComment_FullComment

Просмотреть файл

@ -283,6 +283,20 @@ static void DumpCXCommentInternal(struct CommentASTDumpingContext *Ctx,
PrintCXStringWithPrefixAndDispose( PrintCXStringWithPrefixAndDispose(
"CommandName", "CommandName",
clang_InlineCommandComment_getCommandName(Comment)); clang_InlineCommandComment_getCommandName(Comment));
switch (clang_InlineCommandComment_getRenderKind(Comment)) {
case CXCommentInlineCommandRenderKind_Normal:
printf(" RenderNormal");
break;
case CXCommentInlineCommandRenderKind_Bold:
printf(" RenderBold");
break;
case CXCommentInlineCommandRenderKind_Monospaced:
printf(" RenderMonospaced");
break;
case CXCommentInlineCommandRenderKind_Emphasized:
printf(" RenderEmphasized");
break;
}
for (i = 0, e = clang_InlineCommandComment_getNumArgs(Comment); for (i = 0, e = clang_InlineCommandComment_getNumArgs(Comment);
i != e; ++i) { i != e; ++i) {
printf(" Arg[%u]=", i); printf(" Arg[%u]=", i);

Просмотреть файл

@ -126,6 +126,28 @@ CXString clang_InlineCommandComment_getCommandName(CXComment CXC) {
return createCXString(ICC->getCommandName(), /*DupString=*/ false); return createCXString(ICC->getCommandName(), /*DupString=*/ false);
} }
enum CXCommentInlineCommandRenderKind
clang_InlineCommandComment_getRenderKind(CXComment CXC) {
const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
if (!ICC)
return CXCommentInlineCommandRenderKind_Normal;
switch (ICC->getRenderKind()) {
case InlineCommandComment::RenderNormal:
return CXCommentInlineCommandRenderKind_Normal;
case InlineCommandComment::RenderBold:
return CXCommentInlineCommandRenderKind_Bold;
case InlineCommandComment::RenderMonospaced:
return CXCommentInlineCommandRenderKind_Monospaced;
case InlineCommandComment::RenderEmphasized:
return CXCommentInlineCommandRenderKind_Emphasized;
}
llvm_unreachable("unknown InlineCommandComment::RenderKind");
}
unsigned clang_InlineCommandComment_getNumArgs(CXComment CXC) { unsigned clang_InlineCommandComment_getNumArgs(CXComment CXC) {
const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC); const InlineCommandComment *ICC = getASTNodeAs<InlineCommandComment>(CXC);
if (!ICC) if (!ICC)
@ -344,34 +366,34 @@ void CommentASTToHTMLConverter::visitTextComment(const TextComment *C) {
void CommentASTToHTMLConverter::visitInlineCommandComment( void CommentASTToHTMLConverter::visitInlineCommandComment(
const InlineCommandComment *C) { const InlineCommandComment *C) {
StringRef CommandName = C->getCommandName(); // Nothing to render if no arguments supplied.
bool HasArg0 = C->getNumArgs() > 0 && !C->getArgText(0).empty(); if (C->getNumArgs() == 0)
StringRef Arg0; return;
if (HasArg0)
Arg0 = C->getArgText(0);
if (CommandName == "b") { // Nothing to render if argument is empty.
if (!HasArg0) StringRef Arg0 = C->getArgText(0);
return; if (Arg0.empty())
return;
switch (C->getRenderKind()) {
case InlineCommandComment::RenderNormal:
for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
Result << C->getArgText(i) << " ";
return;
case InlineCommandComment::RenderBold:
assert(C->getNumArgs() == 1);
Result << "<b>" << Arg0 << "</b>"; Result << "<b>" << Arg0 << "</b>";
return; return;
} case InlineCommandComment::RenderMonospaced:
if (CommandName == "c" || CommandName == "p") { assert(C->getNumArgs() == 1);
if (!HasArg0)
return;
Result << "<tt>" << Arg0 << "</tt>"; Result << "<tt>" << Arg0 << "</tt>";
return; return;
} case InlineCommandComment::RenderEmphasized:
if (CommandName == "a" || CommandName == "e" || CommandName == "em") { assert(C->getNumArgs() == 1);
if (!HasArg0)
return;
Result << "<em>" << Arg0 << "</em>"; Result << "<em>" << Arg0 << "</em>";
return; 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) << " ";
} }
void CommentASTToHTMLConverter::visitHTMLStartTagComment( void CommentASTToHTMLConverter::visitHTMLStartTagComment(

Просмотреть файл

@ -25,6 +25,7 @@ clang_Comment_isWhitespace
clang_InlineContentComment_hasTrailingNewline clang_InlineContentComment_hasTrailingNewline
clang_TextComment_getText clang_TextComment_getText
clang_InlineCommandComment_getCommandName clang_InlineCommandComment_getCommandName
clang_InlineCommandComment_getRenderKind
clang_InlineCommandComment_getNumArgs clang_InlineCommandComment_getNumArgs
clang_InlineCommandComment_getArgText clang_InlineCommandComment_getArgText
clang_HTMLTagComment_getTagName clang_HTMLTagComment_getTagName