[Clang-doc] Display values and comments in MD (#183754)
Display enum members in a tabular format in markdown. Support displaying enum member value and comments. Output: | Name | Value | Comments | |---|---|---| | Small | 0 | A pearl.<br>Pearls are quite small.<br><br>Pearls are used in jewelry. | | Medium | 1 | A tennis ball. | | Large | 2 | A football. |
This commit is contained in:
parent
ac2567c9f7
commit
a60fc29236
@ -8,6 +8,7 @@
|
||||
|
||||
#include "Generators.h"
|
||||
#include "Representation.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
@ -67,6 +68,80 @@ static void writeSourceFileRef(const ClangDocContext &CDCtx, const Location &L,
|
||||
OS << "\n\n";
|
||||
}
|
||||
|
||||
/// Writer for writing comments to a table cell in MD.
|
||||
///
|
||||
/// The writer traverses the comments recursively and outputs the
|
||||
/// comments into a stream.
|
||||
/// The formatter inserts single/double line breaks to retain the comment
|
||||
/// structure.
|
||||
///
|
||||
/// Usage :
|
||||
/// Initialize an object with a llvm::raw_ostream to output into.
|
||||
/// Call the write(C) function with an array of Comments 'C'.
|
||||
class TableCommentWriter {
|
||||
public:
|
||||
explicit TableCommentWriter(llvm::raw_ostream &OS) : OS(OS) {}
|
||||
|
||||
void write(llvm::ArrayRef<CommentInfo> Comments) {
|
||||
for (const auto &C : Comments)
|
||||
writeTableSafeComment(C);
|
||||
|
||||
if (!Started)
|
||||
OS << "--";
|
||||
}
|
||||
|
||||
private:
|
||||
/// This function inserts breaks into the stream.
|
||||
///
|
||||
/// We add a double break in between paragraphs.
|
||||
/// Inside a paragraph, a single break between lines is maintained.
|
||||
void insertSeparator() {
|
||||
if (!Started)
|
||||
return;
|
||||
if (NeedsParagraphBreak) {
|
||||
OS << "<br><br>";
|
||||
NeedsParagraphBreak = false;
|
||||
} else {
|
||||
OS << "<br>";
|
||||
}
|
||||
}
|
||||
|
||||
/// This function processes every comment and its children recursively.
|
||||
void writeTableSafeComment(const CommentInfo &I) {
|
||||
switch (I.Kind) {
|
||||
case CommentKind::CK_FullComment:
|
||||
for (const auto &Child : I.Children)
|
||||
writeTableSafeComment(*Child);
|
||||
break;
|
||||
|
||||
case CommentKind::CK_ParagraphComment:
|
||||
for (const auto &Child : I.Children)
|
||||
writeTableSafeComment(*Child);
|
||||
// Next content after a paragraph needs a break
|
||||
NeedsParagraphBreak = true;
|
||||
break;
|
||||
|
||||
case CommentKind::CK_TextComment:
|
||||
if (!I.Text.empty()) {
|
||||
insertSeparator();
|
||||
OS << I.Text;
|
||||
Started = true;
|
||||
}
|
||||
break;
|
||||
|
||||
// Handle other comment types (BlockCommand, InlineCommand, etc.)
|
||||
default:
|
||||
for (const auto &Child : I.Children)
|
||||
writeTableSafeComment(*Child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
llvm::raw_ostream &OS;
|
||||
bool Started = false;
|
||||
bool NeedsParagraphBreak = false;
|
||||
};
|
||||
|
||||
static void maybeWriteSourceFileRef(llvm::raw_ostream &OS,
|
||||
const ClangDocContext &CDCtx,
|
||||
const std::optional<Location> &DefLoc) {
|
||||
@ -163,14 +238,36 @@ static void genMarkdown(const ClangDocContext &CDCtx, const EnumInfo &I,
|
||||
if (I.BaseType && !I.BaseType->Type.QualName.empty()) {
|
||||
OS << ": " << I.BaseType->Type.QualName << " ";
|
||||
}
|
||||
OS << "|\n\n" << "--\n\n";
|
||||
OS << "|\n\n";
|
||||
|
||||
std::string Buffer;
|
||||
llvm::raw_string_ostream Members(Buffer);
|
||||
if (!I.Members.empty())
|
||||
for (const auto &N : I.Members)
|
||||
Members << "| " << N.Name << " |\n";
|
||||
writeLine(Members.str(), OS);
|
||||
OS << "| Name | Value |";
|
||||
if (!I.Members.empty()) {
|
||||
bool HasComments = false;
|
||||
for (const auto &Member : I.Members) {
|
||||
if (!Member.Description.empty()) {
|
||||
HasComments = true;
|
||||
OS << " Comments |";
|
||||
break;
|
||||
}
|
||||
}
|
||||
OS << "\n|---|---|";
|
||||
if (HasComments)
|
||||
OS << "---|";
|
||||
OS << "\n";
|
||||
for (const auto &N : I.Members) {
|
||||
OS << "| " << N.Name << " ";
|
||||
if (!N.Value.empty())
|
||||
OS << "| " << N.Value << " ";
|
||||
if (HasComments) {
|
||||
OS << "| ";
|
||||
TableCommentWriter CommentWriter(OS);
|
||||
CommentWriter.write(N.Description);
|
||||
OS << " ";
|
||||
}
|
||||
OS << "|\n";
|
||||
}
|
||||
}
|
||||
OS << "\n";
|
||||
|
||||
maybeWriteSourceFileRef(OS, CDCtx, I.DefLoc);
|
||||
|
||||
|
||||
@ -41,10 +41,11 @@ enum Color {
|
||||
|
||||
// MD-INDEX: ## Enums
|
||||
// MD-INDEX: | enum Color |
|
||||
// MD-INDEX: --
|
||||
// MD-INDEX: | Red |
|
||||
// MD-INDEX: | Green |
|
||||
// MD-INDEX: | Blue |
|
||||
// MD-INDEX: | Name | Value | Comments |
|
||||
// MD-INDEX: |---|---|---|
|
||||
// MD-INDEX: | Red | 0 | Comment 1 |
|
||||
// MD-INDEX: | Green | 1 | Comment 2 |
|
||||
// MD-INDEX: | Blue | 2 | Comment 3 |
|
||||
// MD-INDEX: **brief** For specifying RGB colors
|
||||
|
||||
// HTML-INDEX-LABEL: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
|
||||
@ -92,7 +93,7 @@ enum Color {
|
||||
// HTML-INDEX-NEXT: <p>For specifying RGB colors</p>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-62]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-63]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
|
||||
// MD-MUSTACHE-INDEX: ## Enums
|
||||
@ -118,11 +119,13 @@ enum class Shapes {
|
||||
/// Comment 3
|
||||
Triangle
|
||||
};
|
||||
|
||||
// MD-INDEX: | enum class Shapes |
|
||||
// MD-INDEX: --
|
||||
// MD-INDEX: | Circle |
|
||||
// MD-INDEX: | Rectangle |
|
||||
// MD-INDEX: | Triangle |
|
||||
// MD-INDEX: | Name | Value | Comments |
|
||||
// MD-INDEX: |---|---|---|
|
||||
// MD-INDEX: | Circle | 0 | Comment 1 |
|
||||
// MD-INDEX: | Rectangle | 1 | Comment 2 |
|
||||
// MD-INDEX: | Triangle | 2 | Comment 3 |
|
||||
// MD-INDEX: **brief** Shape Types
|
||||
|
||||
// HTML-INDEX-LABEL: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
|
||||
@ -170,7 +173,7 @@ enum class Shapes {
|
||||
// HTML-INDEX-NEXT: <p>Shape Types</p>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-64]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-66]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
@ -195,10 +198,11 @@ enum Size : uint8_t {
|
||||
};
|
||||
|
||||
// MD-INDEX: | enum Size : uint8_t |
|
||||
// MD-INDEX: --
|
||||
// MD-INDEX: | Small |
|
||||
// MD-INDEX: | Medium |
|
||||
// MD-INDEX: | Large |
|
||||
// MD-INDEX: | Name | Value | Comments |
|
||||
// MD-INDEX: |---|---|---|
|
||||
// MD-INDEX: | Small | 0 | A pearl.<br>Pearls are quite small.<br><br>Pearls are used in jewelry. |
|
||||
// MD-INDEX: | Medium | 1 | A tennis ball. |
|
||||
// MD-INDEX: | Large | 2 | A football. |
|
||||
// MD-INDEX: **brief** Specify the size
|
||||
|
||||
// HTML-INDEX-LABEL: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
|
||||
@ -248,7 +252,7 @@ enum Size : uint8_t {
|
||||
// HTML-INDEX-NEXT: <p>Specify the size</p>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-71]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-72]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
|
||||
/**
|
||||
@ -261,8 +265,9 @@ enum : long long {
|
||||
};
|
||||
|
||||
// MD-INDEX: | enum (unnamed) : long long |
|
||||
// MD-INDEX: --
|
||||
// MD-INDEX: | BigVal |
|
||||
// MD-INDEX: | Name | Value | Comments |
|
||||
// MD-INDEX: |---|---|---|
|
||||
// MD-INDEX: | BigVal | 999999999999 | A very large value |
|
||||
// MD-INDEX: **brief** Very long number
|
||||
|
||||
// HTML-INDEX-LABEL: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
|
||||
@ -292,7 +297,7 @@ enum : long long {
|
||||
// HTML-INDEX-NEXT: <p>Very long number</p>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-38]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-39]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
|
||||
class FilePermissions {
|
||||
@ -312,10 +317,11 @@ public:
|
||||
};
|
||||
|
||||
// MD-PERM: | enum (unnamed) |
|
||||
// MD-PERM: --
|
||||
// MD-PERM: | Read |
|
||||
// MD-PERM: | Write |
|
||||
// MD-PERM: | Execute |
|
||||
// MD-PERM: | Name | Value | Comments |
|
||||
// MD-PERM: |---|---|---|
|
||||
// MD-PERM: | Read | 1 | Permission to READ r |
|
||||
// MD-PERM: | Write | 2 | Permission to WRITE w |
|
||||
// MD-PERM: | Execute | 4 | Permission to EXECUTE x |
|
||||
// MD-PERM: **brief** File permission flags
|
||||
|
||||
// HTML-PERM-LABEL: <section id="Enums" class="section-container">
|
||||
@ -365,7 +371,7 @@ public:
|
||||
// HTML-PERM-NEXT: <p>File permission flags</p>
|
||||
// HTML-PERM-NEXT: </div>
|
||||
// HTML-PERM-NEXT: </div>
|
||||
// HTML-PERM-NEXT: <p>Defined at line [[@LINE-63]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-PERM-NEXT: <p>Defined at line [[@LINE-64]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-PERM-NEXT: </div>
|
||||
// HTML-PERM-NEXT: </section>
|
||||
|
||||
@ -442,10 +448,11 @@ public:
|
||||
// MD-ANIMAL: # class Animals
|
||||
// MD-ANIMAL: ## Enums
|
||||
// MD-ANIMAL: | enum AnimalType |
|
||||
// MD-ANIMAL: --
|
||||
// MD-ANIMAL: | Dog |
|
||||
// MD-ANIMAL: | Cat |
|
||||
// MD-ANIMAL: | Iguana |
|
||||
// MD-ANIMAL: | Name | Value | Comments |
|
||||
// MD-ANIMAL: |---|---|---|
|
||||
// MD-ANIMAL: | Dog | 0 | Man's best friend |
|
||||
// MD-ANIMAL: | Cat | 1 | Man's other best friend |
|
||||
// MD-ANIMAL: | Iguana | 2 | A lizard |
|
||||
// MD-ANIMAL: **brief** specify what animal the class is
|
||||
|
||||
// MD-MUSTACHE-ANIMAL: # class Animals
|
||||
@ -476,11 +483,12 @@ enum Car {
|
||||
// MD-VEHICLES: # namespace Vehicles
|
||||
// MD-VEHICLES: ## Enums
|
||||
// MD-VEHICLES: | enum Car |
|
||||
// MD-VEHICLES: --
|
||||
// MD-VEHICLES: | Sedan |
|
||||
// MD-VEHICLES: | SUV |
|
||||
// MD-VEHICLES: | Pickup |
|
||||
// MD-VEHICLES: | Hatchback |
|
||||
// MD-VEHICLES: | Name | Value | Comments |
|
||||
// MD-VEHICLES: |---|---|---|
|
||||
// MD-VEHICLES: | Sedan | 0 | Comment 1 |
|
||||
// MD-VEHICLES: | SUV | 1 | Comment 2 |
|
||||
// MD-VEHICLES: | Pickup | 2 | -- |
|
||||
// MD-VEHICLES: | Hatchback | 3 | Comment 4 |
|
||||
// MD-VEHICLES: **brief** specify type of car
|
||||
|
||||
// HTML-VEHICLES-LABEL: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
|
||||
@ -533,7 +541,7 @@ enum Car {
|
||||
// HTML-VEHICLES-NEXT: <p>specify type of car</p>
|
||||
// HTML-VEHICLES-NEXT: </div>
|
||||
// HTML-VEHICLES-NEXT: </div>
|
||||
// HTML-VEHICLES-NEXT: <p>Defined at line [[@LINE-72]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-VEHICLES-NEXT: <p>Defined at line [[@LINE-73]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-VEHICLES-NEXT: </div>
|
||||
|
||||
// MD-MUSTACHE-VEHICLES: # namespace Vehicles
|
||||
@ -553,10 +561,11 @@ enum ColorUserSpecified {
|
||||
};
|
||||
|
||||
// MD-INDEX: | enum ColorUserSpecified |
|
||||
// MD-INDEX: --
|
||||
// MD-INDEX: | RedUserSpecified |
|
||||
// MD-INDEX: | GreenUserSpecified |
|
||||
// MD-INDEX: | BlueUserSpecified |
|
||||
// MD-INDEX: | Name | Value |
|
||||
// MD-INDEX: |---|---|
|
||||
// MD-INDEX: | RedUserSpecified | 65 |
|
||||
// MD-INDEX: | GreenUserSpecified | 2 |
|
||||
// MD-INDEX: | BlueUserSpecified | 67 |
|
||||
|
||||
// HTML-INDEX-LABEL: <div id="{{([0-9A-F]{40})}}" class="delimiter-container">
|
||||
// HTML-INDEX-NEXT: <div>
|
||||
@ -582,7 +591,7 @@ enum ColorUserSpecified {
|
||||
// HTML-INDEX-NEXT: </tr>
|
||||
// HTML-INDEX-NEXT: </tbody>
|
||||
// HTML-INDEX-NEXT: </table>
|
||||
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-36]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-INDEX-NEXT: <p>Defined at line [[@LINE-37]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
|
||||
// HTML-INDEX-NEXT: </div>
|
||||
|
||||
// MD-MUSTACHE-INDEX: | enum ColorUserSpecified |
|
||||
|
||||
@ -69,10 +69,7 @@ TEST_F(MDGeneratorTest, emitNamespaceMD) {
|
||||
|
||||
| enum OneEnum |
|
||||
|
||||
--
|
||||
|
||||
|
||||
|
||||
| Name | Value |
|
||||
|
||||
|
||||
)raw";
|
||||
@ -136,10 +133,7 @@ ChildStruct
|
||||
|
||||
| enum OneEnum |
|
||||
|
||||
--
|
||||
|
||||
|
||||
|
||||
| Name | Value |
|
||||
|
||||
|
||||
)raw";
|
||||
@ -197,10 +191,9 @@ TEST_F(MDGeneratorTest, emitEnumMD) {
|
||||
assert(!Err);
|
||||
std::string Expected = R"raw(| enum class e |
|
||||
|
||||
--
|
||||
|
||||
| X |
|
||||
|
||||
| Name | Value |
|
||||
|---|---|
|
||||
| X | 0 |
|
||||
|
||||
*Defined at test.cpp#10*
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user