Refactor clang doc comment structure (#142273)
This patch refactors CommentKind handling in clang-doc by introducing a strongly typed enum class for better type safety and clarity. It updates all relevant places, including YAML traits and serialization, to work with the new enum. Additionally, it enhances the Mustache-based HTML generation by fully supporting all comment kinds, ensuring accurate structured rendering of comment blocks. The changes simplify future maintenance, improve robustness by eliminating unchecked defaults, and ensure consistency between generators. Fixes https://github.com/llvm/llvm-project/issues/142083
This commit is contained in:
@@ -315,9 +315,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID,
|
||||
|
||||
static llvm::Error parseRecord(const Record &R, unsigned ID,
|
||||
llvm::StringRef Blob, CommentInfo *I) {
|
||||
llvm::SmallString<16> KindStr;
|
||||
switch (ID) {
|
||||
case COMMENT_KIND:
|
||||
return decodeRecord(R, I->Kind, Blob);
|
||||
if (llvm::Error Err = decodeRecord(R, KindStr, Blob))
|
||||
return Err;
|
||||
I->Kind = stringToCommentKind(KindStr);
|
||||
return llvm::Error::success();
|
||||
case COMMENT_TEXT:
|
||||
return decodeRecord(R, I->Text, Blob);
|
||||
case COMMENT_NAME:
|
||||
|
||||
@@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) {
|
||||
|
||||
void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) {
|
||||
StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID);
|
||||
// Handle Kind (enum) separately, since it is not a string.
|
||||
emitRecord(commentKindToString(I.Kind), COMMENT_KIND);
|
||||
for (const auto &L : std::vector<std::pair<llvm::StringRef, RecordId>>{
|
||||
{I.Kind, COMMENT_KIND},
|
||||
{I.Text, COMMENT_TEXT},
|
||||
{I.Name, COMMENT_NAME},
|
||||
{I.Direction, COMMENT_DIRECTION},
|
||||
|
||||
@@ -635,7 +635,8 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) {
|
||||
}
|
||||
|
||||
static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) {
|
||||
if (I.Kind == "FullComment") {
|
||||
switch (I.Kind) {
|
||||
case CommentKind::CK_FullComment: {
|
||||
auto FullComment = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
|
||||
for (const auto &Child : I.Children) {
|
||||
std::unique_ptr<HTMLNode> Node = genHTML(*Child);
|
||||
@@ -645,7 +646,7 @@ static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) {
|
||||
return std::move(FullComment);
|
||||
}
|
||||
|
||||
if (I.Kind == "ParagraphComment") {
|
||||
case CommentKind::CK_ParagraphComment: {
|
||||
auto ParagraphComment = std::make_unique<TagNode>(HTMLTag::TAG_P);
|
||||
for (const auto &Child : I.Children) {
|
||||
std::unique_ptr<HTMLNode> Node = genHTML(*Child);
|
||||
@@ -657,7 +658,7 @@ static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) {
|
||||
return std::move(ParagraphComment);
|
||||
}
|
||||
|
||||
if (I.Kind == "BlockCommandComment") {
|
||||
case CommentKind::CK_BlockCommandComment: {
|
||||
auto BlockComment = std::make_unique<TagNode>(HTMLTag::TAG_DIV);
|
||||
BlockComment->Children.emplace_back(
|
||||
std::make_unique<TagNode>(HTMLTag::TAG_DIV, I.Name));
|
||||
@@ -670,12 +671,26 @@ static std::unique_ptr<HTMLNode> genHTML(const CommentInfo &I) {
|
||||
return nullptr;
|
||||
return std::move(BlockComment);
|
||||
}
|
||||
if (I.Kind == "TextComment") {
|
||||
if (I.Text == "")
|
||||
|
||||
case CommentKind::CK_TextComment: {
|
||||
if (I.Text.empty())
|
||||
return nullptr;
|
||||
return std::make_unique<TextNode>(I.Text);
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
// For now, return nullptr for unsupported comment kinds
|
||||
case CommentKind::CK_InlineCommandComment:
|
||||
case CommentKind::CK_HTMLStartTagComment:
|
||||
case CommentKind::CK_HTMLEndTagComment:
|
||||
case CommentKind::CK_ParamCommandComment:
|
||||
case CommentKind::CK_TParamCommandComment:
|
||||
case CommentKind::CK_VerbatimBlockComment:
|
||||
case CommentKind::CK_VerbatimBlockLineComment:
|
||||
case CommentKind::CK_VerbatimLineComment:
|
||||
case CommentKind::CK_Unknown:
|
||||
return nullptr;
|
||||
}
|
||||
llvm_unreachable("Unhandled CommentKind");
|
||||
}
|
||||
|
||||
static std::unique_ptr<TagNode> genHTML(const std::vector<CommentInfo> &C) {
|
||||
|
||||
@@ -208,37 +208,110 @@ static json::Value extractValue(const TypedefInfo &I) {
|
||||
}
|
||||
|
||||
static json::Value extractValue(const CommentInfo &I) {
|
||||
assert((I.Kind == "BlockCommandComment" || I.Kind == "FullComment" ||
|
||||
I.Kind == "ParagraphComment" || I.Kind == "TextComment") &&
|
||||
"Unknown Comment type in CommentInfo.");
|
||||
|
||||
Object Obj = Object();
|
||||
json::Value Child = Object();
|
||||
|
||||
// TextComment has no children, so return it.
|
||||
if (I.Kind == "TextComment") {
|
||||
Obj.insert({"TextComment", I.Text});
|
||||
return Obj;
|
||||
}
|
||||
json::Value ChildVal = Object();
|
||||
Object &Child = *ChildVal.getAsObject();
|
||||
|
||||
// BlockCommandComment needs to generate a Command key.
|
||||
if (I.Kind == "BlockCommandComment")
|
||||
Child.getAsObject()->insert({"Command", I.Name});
|
||||
|
||||
// Use the same handling for everything else.
|
||||
// Only valid for:
|
||||
// - BlockCommandComment
|
||||
// - FullComment
|
||||
// - ParagraphComment
|
||||
json::Value ChildArr = Array();
|
||||
auto &CARef = *ChildArr.getAsArray();
|
||||
CARef.reserve(I.Children.size());
|
||||
for (const auto &C : I.Children)
|
||||
CARef.emplace_back(extractValue(*C));
|
||||
Child.getAsObject()->insert({"Children", ChildArr});
|
||||
Obj.insert({I.Kind, Child});
|
||||
|
||||
return Obj;
|
||||
switch (I.Kind) {
|
||||
case CommentKind::CK_TextComment: {
|
||||
Obj.insert({commentKindToString(I.Kind), I.Text});
|
||||
return Obj;
|
||||
}
|
||||
|
||||
case CommentKind::CK_BlockCommandComment: {
|
||||
Child.insert({"Command", I.Name});
|
||||
Child.insert({"Children", ChildArr});
|
||||
Obj.insert({commentKindToString(I.Kind), ChildVal});
|
||||
return Obj;
|
||||
}
|
||||
|
||||
case CommentKind::CK_InlineCommandComment: {
|
||||
json::Value ArgsArr = Array();
|
||||
auto &ARef = *ArgsArr.getAsArray();
|
||||
ARef.reserve(I.Args.size());
|
||||
for (const auto &Arg : I.Args)
|
||||
ARef.emplace_back(Arg);
|
||||
Child.insert({"Command", I.Name});
|
||||
Child.insert({"Args", ArgsArr});
|
||||
Child.insert({"Children", ChildArr});
|
||||
Obj.insert({commentKindToString(I.Kind), ChildVal});
|
||||
return Obj;
|
||||
}
|
||||
|
||||
case CommentKind::CK_ParamCommandComment:
|
||||
case CommentKind::CK_TParamCommandComment: {
|
||||
Child.insert({"ParamName", I.ParamName});
|
||||
Child.insert({"Direction", I.Direction});
|
||||
Child.insert({"Explicit", I.Explicit});
|
||||
Child.insert({"Children", ChildArr});
|
||||
Obj.insert({commentKindToString(I.Kind), ChildVal});
|
||||
return Obj;
|
||||
}
|
||||
|
||||
case CommentKind::CK_VerbatimBlockComment: {
|
||||
Child.insert({"Text", I.Text});
|
||||
if (!I.CloseName.empty())
|
||||
Child.insert({"CloseName", I.CloseName});
|
||||
Child.insert({"Children", ChildArr});
|
||||
Obj.insert({commentKindToString(I.Kind), ChildVal});
|
||||
return Obj;
|
||||
}
|
||||
|
||||
case CommentKind::CK_VerbatimBlockLineComment:
|
||||
case CommentKind::CK_VerbatimLineComment: {
|
||||
Child.insert({"Text", I.Text});
|
||||
Child.insert({"Children", ChildArr});
|
||||
Obj.insert({commentKindToString(I.Kind), ChildVal});
|
||||
return Obj;
|
||||
}
|
||||
|
||||
case CommentKind::CK_HTMLStartTagComment: {
|
||||
json::Value AttrKeysArray = json::Array();
|
||||
json::Value AttrValuesArray = json::Array();
|
||||
auto &KeyArr = *AttrKeysArray.getAsArray();
|
||||
auto &ValArr = *AttrValuesArray.getAsArray();
|
||||
KeyArr.reserve(I.AttrKeys.size());
|
||||
ValArr.reserve(I.AttrValues.size());
|
||||
for (const auto &K : I.AttrKeys)
|
||||
KeyArr.emplace_back(K);
|
||||
for (const auto &V : I.AttrValues)
|
||||
ValArr.emplace_back(V);
|
||||
Child.insert({"Name", I.Name});
|
||||
Child.insert({"SelfClosing", I.SelfClosing});
|
||||
Child.insert({"AttrKeys", AttrKeysArray});
|
||||
Child.insert({"AttrValues", AttrValuesArray});
|
||||
Child.insert({"Children", ChildArr});
|
||||
Obj.insert({commentKindToString(I.Kind), ChildVal});
|
||||
return Obj;
|
||||
}
|
||||
|
||||
case CommentKind::CK_HTMLEndTagComment: {
|
||||
Child.insert({"Name", I.Name});
|
||||
Child.insert({"Children", ChildArr});
|
||||
Obj.insert({commentKindToString(I.Kind), ChildVal});
|
||||
return Obj;
|
||||
}
|
||||
|
||||
case CommentKind::CK_FullComment:
|
||||
case CommentKind::CK_ParagraphComment: {
|
||||
Child.insert({"Children", ChildArr});
|
||||
Obj.insert({commentKindToString(I.Kind), ChildVal});
|
||||
return Obj;
|
||||
}
|
||||
|
||||
case CommentKind::CK_Unknown: {
|
||||
Obj.insert({commentKindToString(I.Kind), I.Text});
|
||||
return Obj;
|
||||
}
|
||||
}
|
||||
llvm_unreachable("Unknown comment kind encountered.");
|
||||
}
|
||||
|
||||
static void maybeInsertLocation(std::optional<Location> Loc,
|
||||
@@ -255,6 +328,7 @@ static void extractDescriptionFromInfo(ArrayRef<CommentInfo> Descriptions,
|
||||
return;
|
||||
json::Value DescArr = Array();
|
||||
json::Array &DescARef = *DescArr.getAsArray();
|
||||
DescARef.reserve(Descriptions.size());
|
||||
for (const CommentInfo &Child : Descriptions)
|
||||
DescARef.emplace_back(extractValue(Child));
|
||||
EnumValObj.insert({"EnumValueComments", DescArr});
|
||||
@@ -270,6 +344,7 @@ static json::Value extractValue(const FunctionInfo &I, StringRef ParentInfoDir,
|
||||
|
||||
json::Value ParamArr = Array();
|
||||
json::Array &ParamARef = *ParamArr.getAsArray();
|
||||
ParamARef.reserve(I.Params.size());
|
||||
for (const auto Val : enumerate(I.Params)) {
|
||||
json::Value V = Object();
|
||||
auto &VRef = *V.getAsObject();
|
||||
@@ -297,6 +372,7 @@ static json::Value extractValue(const EnumInfo &I,
|
||||
Obj.insert({"ID", toHex(toStringRef(I.USR))});
|
||||
json::Value EnumArr = Array();
|
||||
json::Array &EnumARef = *EnumArr.getAsArray();
|
||||
EnumARef.reserve(I.Members.size());
|
||||
for (const EnumValueInfo &M : I.Members) {
|
||||
json::Value EnumValue = Object();
|
||||
auto &EnumValObj = *EnumValue.getAsObject();
|
||||
@@ -322,6 +398,7 @@ static void extractScopeChildren(const ScopeChildren &S, Object &Obj,
|
||||
const ClangDocContext &CDCtx) {
|
||||
json::Value NamespaceArr = Array();
|
||||
json::Array &NamespaceARef = *NamespaceArr.getAsArray();
|
||||
NamespaceARef.reserve(S.Namespaces.size());
|
||||
for (const Reference &Child : S.Namespaces)
|
||||
NamespaceARef.emplace_back(extractValue(Child, ParentInfoDir));
|
||||
|
||||
@@ -330,6 +407,7 @@ static void extractScopeChildren(const ScopeChildren &S, Object &Obj,
|
||||
|
||||
json::Value RecordArr = Array();
|
||||
json::Array &RecordARef = *RecordArr.getAsArray();
|
||||
RecordARef.reserve(S.Records.size());
|
||||
for (const Reference &Child : S.Records)
|
||||
RecordARef.emplace_back(extractValue(Child, ParentInfoDir));
|
||||
|
||||
@@ -338,12 +416,15 @@ static void extractScopeChildren(const ScopeChildren &S, Object &Obj,
|
||||
|
||||
json::Value FunctionArr = Array();
|
||||
json::Array &FunctionARef = *FunctionArr.getAsArray();
|
||||
FunctionARef.reserve(S.Functions.size());
|
||||
|
||||
json::Value PublicFunctionArr = Array();
|
||||
json::Array &PublicFunctionARef = *PublicFunctionArr.getAsArray();
|
||||
PublicFunctionARef.reserve(S.Functions.size());
|
||||
|
||||
json::Value ProtectedFunctionArr = Array();
|
||||
json::Array &ProtectedFunctionARef = *ProtectedFunctionArr.getAsArray();
|
||||
ProtectedFunctionARef.reserve(S.Functions.size());
|
||||
|
||||
for (const FunctionInfo &Child : S.Functions) {
|
||||
json::Value F = extractValue(Child, ParentInfoDir, CDCtx);
|
||||
@@ -367,6 +448,7 @@ static void extractScopeChildren(const ScopeChildren &S, Object &Obj,
|
||||
|
||||
json::Value EnumArr = Array();
|
||||
auto &EnumARef = *EnumArr.getAsArray();
|
||||
EnumARef.reserve(S.Enums.size());
|
||||
for (const EnumInfo &Child : S.Enums)
|
||||
EnumARef.emplace_back(extractValue(Child, CDCtx));
|
||||
|
||||
@@ -375,6 +457,7 @@ static void extractScopeChildren(const ScopeChildren &S, Object &Obj,
|
||||
|
||||
json::Value TypedefArr = Array();
|
||||
auto &TypedefARef = *TypedefArr.getAsArray();
|
||||
TypedefARef.reserve(S.Typedefs.size());
|
||||
for (const TypedefInfo &Child : S.Typedefs)
|
||||
TypedefARef.emplace_back(extractValue(Child));
|
||||
|
||||
@@ -411,10 +494,13 @@ static json::Value extractValue(const RecordInfo &I,
|
||||
extractScopeChildren(I.Children, RecordValue, BasePath, CDCtx);
|
||||
json::Value PublicMembers = Array();
|
||||
json::Array &PubMemberRef = *PublicMembers.getAsArray();
|
||||
PubMemberRef.reserve(I.Members.size());
|
||||
json::Value ProtectedMembers = Array();
|
||||
json::Array &ProtMemberRef = *ProtectedMembers.getAsArray();
|
||||
ProtMemberRef.reserve(I.Members.size());
|
||||
json::Value PrivateMembers = Array();
|
||||
json::Array &PrivMemberRef = *PrivateMembers.getAsArray();
|
||||
PrivMemberRef.reserve(I.Members.size());
|
||||
for (const MemberTypeInfo &Member : I.Members) {
|
||||
json::Value MemberValue = Object();
|
||||
auto &MVRef = *MemberValue.getAsObject();
|
||||
@@ -446,20 +532,25 @@ static Error setupTemplateValue(const ClangDocContext &CDCtx, json::Value &V,
|
||||
auto InfoPath = I->getRelativeFilePath("");
|
||||
SmallString<128> RelativePath = computeRelativePath("", InfoPath);
|
||||
sys::path::native(RelativePath, sys::path::Style::posix);
|
||||
|
||||
auto *SSA = StylesheetArr.getAsArray();
|
||||
SSA->reserve(CDCtx.UserStylesheets.size());
|
||||
for (const auto &FilePath : CDCtx.UserStylesheets) {
|
||||
SmallString<128> StylesheetPath = RelativePath;
|
||||
sys::path::append(StylesheetPath, sys::path::Style::posix,
|
||||
sys::path::filename(FilePath));
|
||||
StylesheetArr.getAsArray()->emplace_back(StylesheetPath);
|
||||
SSA->emplace_back(StylesheetPath);
|
||||
}
|
||||
V.getAsObject()->insert({"Stylesheets", StylesheetArr});
|
||||
|
||||
json::Value ScriptArr = Array();
|
||||
auto *SCA = ScriptArr.getAsArray();
|
||||
SCA->reserve(CDCtx.JsScripts.size());
|
||||
for (auto Script : CDCtx.JsScripts) {
|
||||
SmallString<128> JsPath = RelativePath;
|
||||
sys::path::append(JsPath, sys::path::Style::posix,
|
||||
sys::path::filename(Script));
|
||||
ScriptArr.getAsArray()->emplace_back(JsPath);
|
||||
SCA->emplace_back(JsPath);
|
||||
}
|
||||
V.getAsObject()->insert({"Scripts", ScriptArr});
|
||||
return Error::success();
|
||||
|
||||
@@ -75,39 +75,49 @@ static void maybeWriteSourceFileRef(llvm::raw_ostream &OS,
|
||||
}
|
||||
|
||||
static void writeDescription(const CommentInfo &I, raw_ostream &OS) {
|
||||
if (I.Kind == "FullComment") {
|
||||
switch (I.Kind) {
|
||||
case CommentKind::CK_FullComment:
|
||||
for (const auto &Child : I.Children)
|
||||
writeDescription(*Child, OS);
|
||||
} else if (I.Kind == "ParagraphComment") {
|
||||
break;
|
||||
|
||||
case CommentKind::CK_ParagraphComment:
|
||||
for (const auto &Child : I.Children)
|
||||
writeDescription(*Child, OS);
|
||||
writeNewLine(OS);
|
||||
} else if (I.Kind == "BlockCommandComment") {
|
||||
break;
|
||||
|
||||
case CommentKind::CK_BlockCommandComment:
|
||||
OS << genEmphasis(I.Name);
|
||||
for (const auto &Child : I.Children)
|
||||
writeDescription(*Child, OS);
|
||||
} else if (I.Kind == "InlineCommandComment") {
|
||||
break;
|
||||
|
||||
case CommentKind::CK_InlineCommandComment:
|
||||
OS << genEmphasis(I.Name) << " " << I.Text;
|
||||
} else if (I.Kind == "ParamCommandComment") {
|
||||
break;
|
||||
|
||||
case CommentKind::CK_ParamCommandComment:
|
||||
case CommentKind::CK_TParamCommandComment: {
|
||||
std::string Direction = I.Explicit ? (" " + I.Direction).str() : "";
|
||||
OS << genEmphasis(I.ParamName) << I.Text << Direction;
|
||||
for (const auto &Child : I.Children)
|
||||
writeDescription(*Child, OS);
|
||||
} else if (I.Kind == "TParamCommandComment") {
|
||||
std::string Direction = I.Explicit ? (" " + I.Direction).str() : "";
|
||||
OS << genEmphasis(I.ParamName) << I.Text << Direction;
|
||||
break;
|
||||
}
|
||||
|
||||
case CommentKind::CK_VerbatimBlockComment:
|
||||
for (const auto &Child : I.Children)
|
||||
writeDescription(*Child, OS);
|
||||
} else if (I.Kind == "VerbatimBlockComment") {
|
||||
for (const auto &Child : I.Children)
|
||||
writeDescription(*Child, OS);
|
||||
} else if (I.Kind == "VerbatimBlockLineComment") {
|
||||
break;
|
||||
|
||||
case CommentKind::CK_VerbatimBlockLineComment:
|
||||
case CommentKind::CK_VerbatimLineComment:
|
||||
OS << I.Text;
|
||||
writeNewLine(OS);
|
||||
} else if (I.Kind == "VerbatimLineComment") {
|
||||
OS << I.Text;
|
||||
writeNewLine(OS);
|
||||
} else if (I.Kind == "HTMLStartTagComment") {
|
||||
break;
|
||||
|
||||
case CommentKind::CK_HTMLStartTagComment: {
|
||||
if (I.AttrKeys.size() != I.AttrValues.size())
|
||||
return;
|
||||
std::string Buffer;
|
||||
@@ -117,12 +127,20 @@ static void writeDescription(const CommentInfo &I, raw_ostream &OS) {
|
||||
|
||||
std::string CloseTag = I.SelfClosing ? "/>" : ">";
|
||||
writeLine("<" + I.Name + Attrs.str() + CloseTag, OS);
|
||||
} else if (I.Kind == "HTMLEndTagComment") {
|
||||
break;
|
||||
}
|
||||
|
||||
case CommentKind::CK_HTMLEndTagComment:
|
||||
writeLine("</" + I.Name + ">", OS);
|
||||
} else if (I.Kind == "TextComment") {
|
||||
break;
|
||||
|
||||
case CommentKind::CK_TextComment:
|
||||
OS << I.Text;
|
||||
} else {
|
||||
OS << "Unknown comment kind: " << I.Kind << ".\n\n";
|
||||
break;
|
||||
|
||||
case CommentKind::CK_Unknown:
|
||||
OS << "Unknown comment kind: " << static_cast<int>(I.Kind) << ".\n\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,68 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "Representation.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
|
||||
namespace clang {
|
||||
namespace doc {
|
||||
|
||||
CommentKind stringToCommentKind(llvm::StringRef KindStr) {
|
||||
static const llvm::StringMap<CommentKind> KindMap = {
|
||||
{"FullComment", CommentKind::CK_FullComment},
|
||||
{"ParagraphComment", CommentKind::CK_ParagraphComment},
|
||||
{"TextComment", CommentKind::CK_TextComment},
|
||||
{"InlineCommandComment", CommentKind::CK_InlineCommandComment},
|
||||
{"HTMLStartTagComment", CommentKind::CK_HTMLStartTagComment},
|
||||
{"HTMLEndTagComment", CommentKind::CK_HTMLEndTagComment},
|
||||
{"BlockCommandComment", CommentKind::CK_BlockCommandComment},
|
||||
{"ParamCommandComment", CommentKind::CK_ParamCommandComment},
|
||||
{"TParamCommandComment", CommentKind::CK_TParamCommandComment},
|
||||
{"VerbatimBlockComment", CommentKind::CK_VerbatimBlockComment},
|
||||
{"VerbatimBlockLineComment", CommentKind::CK_VerbatimBlockLineComment},
|
||||
{"VerbatimLineComment", CommentKind::CK_VerbatimLineComment},
|
||||
};
|
||||
|
||||
auto It = KindMap.find(KindStr);
|
||||
if (It != KindMap.end()) {
|
||||
return It->second;
|
||||
}
|
||||
return CommentKind::CK_Unknown;
|
||||
}
|
||||
|
||||
llvm::StringRef commentKindToString(CommentKind Kind) {
|
||||
switch (Kind) {
|
||||
case CommentKind::CK_FullComment:
|
||||
return "FullComment";
|
||||
case CommentKind::CK_ParagraphComment:
|
||||
return "ParagraphComment";
|
||||
case CommentKind::CK_TextComment:
|
||||
return "TextComment";
|
||||
case CommentKind::CK_InlineCommandComment:
|
||||
return "InlineCommandComment";
|
||||
case CommentKind::CK_HTMLStartTagComment:
|
||||
return "HTMLStartTagComment";
|
||||
case CommentKind::CK_HTMLEndTagComment:
|
||||
return "HTMLEndTagComment";
|
||||
case CommentKind::CK_BlockCommandComment:
|
||||
return "BlockCommandComment";
|
||||
case CommentKind::CK_ParamCommandComment:
|
||||
return "ParamCommandComment";
|
||||
case CommentKind::CK_TParamCommandComment:
|
||||
return "TParamCommandComment";
|
||||
case CommentKind::CK_VerbatimBlockComment:
|
||||
return "VerbatimBlockComment";
|
||||
case CommentKind::CK_VerbatimBlockLineComment:
|
||||
return "VerbatimBlockLineComment";
|
||||
case CommentKind::CK_VerbatimLineComment:
|
||||
return "VerbatimLineComment";
|
||||
case CommentKind::CK_Unknown:
|
||||
return "Unknown";
|
||||
}
|
||||
llvm_unreachable("Unhandled CommentKind");
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const SymbolID EmptySID = SymbolID();
|
||||
|
||||
@@ -45,6 +45,25 @@ enum class InfoType {
|
||||
IT_typedef
|
||||
};
|
||||
|
||||
enum class CommentKind {
|
||||
CK_FullComment,
|
||||
CK_ParagraphComment,
|
||||
CK_TextComment,
|
||||
CK_InlineCommandComment,
|
||||
CK_HTMLStartTagComment,
|
||||
CK_HTMLEndTagComment,
|
||||
CK_BlockCommandComment,
|
||||
CK_ParamCommandComment,
|
||||
CK_TParamCommandComment,
|
||||
CK_VerbatimBlockComment,
|
||||
CK_VerbatimBlockLineComment,
|
||||
CK_VerbatimLineComment,
|
||||
CK_Unknown
|
||||
};
|
||||
|
||||
CommentKind stringToCommentKind(llvm::StringRef KindStr);
|
||||
llvm::StringRef commentKindToString(CommentKind Kind);
|
||||
|
||||
// A representation of a parsed comment.
|
||||
struct CommentInfo {
|
||||
CommentInfo() = default;
|
||||
@@ -60,13 +79,13 @@ struct CommentInfo {
|
||||
// the vector.
|
||||
bool operator<(const CommentInfo &Other) const;
|
||||
|
||||
// TODO: The Kind field should be an enum, so we can switch on it easily.
|
||||
SmallString<16>
|
||||
Kind; // Kind of comment (FullComment, ParagraphComment, TextComment,
|
||||
// InlineCommandComment, HTMLStartTagComment, HTMLEndTagComment,
|
||||
// BlockCommandComment, ParamCommandComment,
|
||||
// TParamCommandComment, VerbatimBlockComment,
|
||||
// VerbatimBlockLineComment, VerbatimLineComment).
|
||||
CommentKind Kind = CommentKind::
|
||||
CK_Unknown; // Kind of comment (FullComment, ParagraphComment,
|
||||
// TextComment, InlineCommandComment, HTMLStartTagComment,
|
||||
// HTMLEndTagComment, BlockCommandComment,
|
||||
// ParamCommandComment, TParamCommandComment,
|
||||
// VerbatimBlockComment, VerbatimBlockLineComment,
|
||||
// VerbatimLineComment).
|
||||
SmallString<64> Text; // Text of the comment.
|
||||
SmallString<16> Name; // Name of the comment (for Verbatim and HTML).
|
||||
SmallString<8> Direction; // Parameter direction (for (T)ParamCommand).
|
||||
|
||||
@@ -270,7 +270,7 @@ private:
|
||||
};
|
||||
|
||||
void ClangDocCommentVisitor::parseComment(const comments::Comment *C) {
|
||||
CurrentCI.Kind = C->getCommentKindName();
|
||||
CurrentCI.Kind = stringToCommentKind(C->getCommentKindName());
|
||||
ConstCommentVisitor<ClangDocCommentVisitor>::visit(C);
|
||||
for (comments::Comment *Child :
|
||||
llvm::make_range(C->child_begin(), C->child_end())) {
|
||||
|
||||
@@ -65,6 +65,34 @@ template <> struct ScalarEnumerationTraits<InfoType> {
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct ScalarEnumerationTraits<clang::doc::CommentKind> {
|
||||
static void enumeration(IO &IO, clang::doc::CommentKind &Value) {
|
||||
IO.enumCase(Value, "FullComment", clang::doc::CommentKind::CK_FullComment);
|
||||
IO.enumCase(Value, "ParagraphComment",
|
||||
clang::doc::CommentKind::CK_ParagraphComment);
|
||||
IO.enumCase(Value, "TextComment", clang::doc::CommentKind::CK_TextComment);
|
||||
IO.enumCase(Value, "InlineCommandComment",
|
||||
clang::doc::CommentKind::CK_InlineCommandComment);
|
||||
IO.enumCase(Value, "HTMLStartTagComment",
|
||||
clang::doc::CommentKind::CK_HTMLStartTagComment);
|
||||
IO.enumCase(Value, "HTMLEndTagComment",
|
||||
clang::doc::CommentKind::CK_HTMLEndTagComment);
|
||||
IO.enumCase(Value, "BlockCommandComment",
|
||||
clang::doc::CommentKind::CK_BlockCommandComment);
|
||||
IO.enumCase(Value, "ParamCommandComment",
|
||||
clang::doc::CommentKind::CK_ParamCommandComment);
|
||||
IO.enumCase(Value, "TParamCommandComment",
|
||||
clang::doc::CommentKind::CK_TParamCommandComment);
|
||||
IO.enumCase(Value, "VerbatimBlockComment",
|
||||
clang::doc::CommentKind::CK_VerbatimBlockComment);
|
||||
IO.enumCase(Value, "VerbatimBlockLineComment",
|
||||
clang::doc::CommentKind::CK_VerbatimBlockLineComment);
|
||||
IO.enumCase(Value, "VerbatimLineComment",
|
||||
clang::doc::CommentKind::CK_VerbatimLineComment);
|
||||
IO.enumCase(Value, "Unknown", clang::doc::CommentKind::CK_Unknown);
|
||||
}
|
||||
};
|
||||
|
||||
// Scalars to YAML output.
|
||||
template <unsigned U> struct ScalarTraits<SmallString<U>> {
|
||||
|
||||
@@ -149,7 +177,7 @@ static void recordInfoMapping(IO &IO, RecordInfo &I) {
|
||||
}
|
||||
|
||||
static void commentInfoMapping(IO &IO, CommentInfo &I) {
|
||||
IO.mapOptional("Kind", I.Kind, SmallString<16>());
|
||||
IO.mapOptional("Kind", I.Kind, CommentKind::CK_Unknown);
|
||||
IO.mapOptional("Text", I.Text, SmallString<64>());
|
||||
IO.mapOptional("Name", I.Name, SmallString<16>());
|
||||
IO.mapOptional("Direction", I.Direction, SmallString<8>());
|
||||
|
||||
@@ -112,22 +112,22 @@ tuple<int, int, bool> func_with_tuple_param(tuple<int, int, bool> t) { return t;
|
||||
// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: Name: 'func_with_tuple_param'
|
||||
// YAML-NEXT: Description:
|
||||
// YAML-NEXT: - Kind: 'FullComment'
|
||||
// YAML-NEXT: - Kind: FullComment
|
||||
// YAML-NEXT: Children:
|
||||
// YAML-NEXT: - Kind: 'ParagraphComment'
|
||||
// YAML-NEXT: - Kind: ParagraphComment
|
||||
// YAML-NEXT: Children:
|
||||
// YAML-NEXT: - Kind: 'TextComment'
|
||||
// YAML-NEXT: - Kind: TextComment
|
||||
// YAML-NEXT: Text: ' A function with a tuple parameter'
|
||||
// YAML-NEXT: - Kind: 'ParagraphComment'
|
||||
// YAML-NEXT: - Kind: ParagraphComment
|
||||
// YAML-NEXT: Children:
|
||||
// YAML-NEXT: - Kind: 'TextComment'
|
||||
// YAML-NEXT: - Kind: 'ParamCommandComment'
|
||||
// YAML-NEXT: - Kind: TextComment
|
||||
// YAML-NEXT: - Kind: ParamCommandComment
|
||||
// YAML-NEXT: Direction: '[in]'
|
||||
// YAML-NEXT: ParamName: 't'
|
||||
// YAML-NEXT: Children:
|
||||
// YAML-NEXT: - Kind: 'ParagraphComment'
|
||||
// YAML-NEXT: - Kind: ParagraphComment
|
||||
// YAML-NEXT: Children:
|
||||
// YAML-NEXT: - Kind: 'TextComment'
|
||||
// YAML-NEXT: - Kind: TextComment
|
||||
// YAML-NEXT: Text: ' The input to func_with_tuple_param'
|
||||
// YAML-NEXT: DefLocation:
|
||||
// YAML-NEXT: LineNumber: [[# @LINE - 23]]
|
||||
|
||||
@@ -93,12 +93,12 @@ TEST(BitcodeTest, emitRecordInfoBitcode) {
|
||||
|
||||
// Documentation for the data member.
|
||||
CommentInfo TopComment;
|
||||
TopComment.Kind = "FullComment";
|
||||
TopComment.Kind = CommentKind::CK_FullComment;
|
||||
TopComment.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Brief = TopComment.Children.back().get();
|
||||
Brief->Kind = "ParagraphComment";
|
||||
Brief->Kind = CommentKind::CK_ParagraphComment;
|
||||
Brief->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Brief->Children.back()->Kind = "TextComment";
|
||||
Brief->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Brief->Children.back()->Name = "ParagraphComment";
|
||||
Brief->Children.back()->Text = "Value of the thing.";
|
||||
I.Bases.back().Members.back().Description.emplace_back(std::move(TopComment));
|
||||
@@ -184,13 +184,13 @@ TEST(BitcodeTest, emitTypedefInfoBitcode) {
|
||||
I.IsUsing = true;
|
||||
|
||||
CommentInfo Top;
|
||||
Top.Kind = "FullComment";
|
||||
Top.Kind = CommentKind::CK_FullComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *BlankLine = Top.Children.back().get();
|
||||
BlankLine->Kind = "ParagraphComment";
|
||||
BlankLine->Kind = CommentKind::CK_ParagraphComment;
|
||||
BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
BlankLine->Children.back()->Kind = "TextComment";
|
||||
BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
|
||||
I.Description.emplace_back(std::move(Top));
|
||||
|
||||
@@ -220,103 +220,105 @@ TEST(SerializeTest, emitInfoWithCommentBitcode) {
|
||||
F.Params.emplace_back(TypeInfo("int"), "I");
|
||||
|
||||
CommentInfo Top;
|
||||
Top.Kind = "FullComment";
|
||||
Top.Kind = CommentKind::CK_FullComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *BlankLine = Top.Children.back().get();
|
||||
BlankLine->Kind = "ParagraphComment";
|
||||
BlankLine->Kind = CommentKind::CK_ParagraphComment;
|
||||
BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
BlankLine->Children.back()->Kind = "TextComment";
|
||||
BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Brief = Top.Children.back().get();
|
||||
Brief->Kind = "ParagraphComment";
|
||||
Brief->Kind = CommentKind::CK_ParagraphComment;
|
||||
Brief->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Brief->Children.back()->Kind = "TextComment";
|
||||
Brief->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Brief->Children.back()->Name = "ParagraphComment";
|
||||
Brief->Children.back()->Text = " Brief description.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Extended = Top.Children.back().get();
|
||||
Extended->Kind = "ParagraphComment";
|
||||
Extended->Kind = CommentKind::CK_ParagraphComment;
|
||||
Extended->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Extended->Children.back()->Kind = "TextComment";
|
||||
Extended->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Extended->Children.back()->Text = " Extended description that";
|
||||
Extended->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Extended->Children.back()->Kind = "TextComment";
|
||||
Extended->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Extended->Children.back()->Text = " continues onto the next line.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *HTML = Top.Children.back().get();
|
||||
HTML->Kind = "ParagraphComment";
|
||||
HTML->Kind = CommentKind::CK_ParagraphComment;
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "TextComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "HTMLStartTagComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
|
||||
HTML->Children.back()->Name = "ul";
|
||||
HTML->Children.back()->AttrKeys.emplace_back("class");
|
||||
HTML->Children.back()->AttrValues.emplace_back("test");
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "HTMLStartTagComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
|
||||
HTML->Children.back()->Name = "li";
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "TextComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
HTML->Children.back()->Text = " Testing.";
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "HTMLEndTagComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_HTMLEndTagComment;
|
||||
HTML->Children.back()->Name = "ul";
|
||||
HTML->Children.back()->SelfClosing = true;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Verbatim = Top.Children.back().get();
|
||||
Verbatim->Kind = "VerbatimBlockComment";
|
||||
Verbatim->Kind = CommentKind::CK_VerbatimBlockComment;
|
||||
Verbatim->Name = "verbatim";
|
||||
Verbatim->CloseName = "endverbatim";
|
||||
Verbatim->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Verbatim->Children.back()->Kind = "VerbatimBlockLineComment";
|
||||
Verbatim->Children.back()->Kind = CommentKind::CK_VerbatimBlockLineComment;
|
||||
Verbatim->Children.back()->Text = " The description continues.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *ParamOut = Top.Children.back().get();
|
||||
ParamOut->Kind = "ParamCommandComment";
|
||||
ParamOut->Kind = CommentKind::CK_ParamCommandComment;
|
||||
ParamOut->Direction = "[out]";
|
||||
ParamOut->ParamName = "I";
|
||||
ParamOut->Explicit = true;
|
||||
ParamOut->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
ParamOut->Children.back()->Kind = "ParagraphComment";
|
||||
ParamOut->Children.back()->Kind = CommentKind::CK_ParagraphComment;
|
||||
ParamOut->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamOut->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamOut->Children.back()->Children.back()->Kind =
|
||||
CommentKind::CK_TextComment;
|
||||
ParamOut->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamOut->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamOut->Children.back()->Children.back()->Kind =
|
||||
CommentKind::CK_TextComment;
|
||||
ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *ParamIn = Top.Children.back().get();
|
||||
ParamIn->Kind = "ParamCommandComment";
|
||||
ParamIn->Kind = CommentKind::CK_ParamCommandComment;
|
||||
ParamIn->Direction = "[in]";
|
||||
ParamIn->ParamName = "J";
|
||||
ParamIn->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
ParamIn->Children.back()->Kind = "ParagraphComment";
|
||||
ParamIn->Children.back()->Kind = CommentKind::CK_ParagraphComment;
|
||||
ParamIn->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamIn->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
|
||||
ParamIn->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamIn->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Return = Top.Children.back().get();
|
||||
Return->Kind = "BlockCommandComment";
|
||||
Return->Kind = CommentKind::CK_BlockCommandComment;
|
||||
Return->Name = "return";
|
||||
Return->Explicit = true;
|
||||
Return->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Return->Children.back()->Kind = "ParagraphComment";
|
||||
Return->Children.back()->Kind = CommentKind::CK_ParagraphComment;
|
||||
Return->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
Return->Children.back()->Children.back()->Kind = "TextComment";
|
||||
Return->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Return->Children.back()->Children.back()->Text = "void";
|
||||
|
||||
F.Description.emplace_back(std::move(Top));
|
||||
|
||||
@@ -407,37 +407,37 @@ TEST(HTMLGeneratorTest, emitCommentHTML) {
|
||||
I.Access = AccessSpecifier::AS_none;
|
||||
|
||||
CommentInfo Top;
|
||||
Top.Kind = "FullComment";
|
||||
Top.Kind = CommentKind::CK_FullComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *BlankLine = Top.Children.back().get();
|
||||
BlankLine->Kind = "ParagraphComment";
|
||||
BlankLine->Kind = CommentKind::CK_ParagraphComment;
|
||||
BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
BlankLine->Children.back()->Kind = "TextComment";
|
||||
BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Brief = Top.Children.back().get();
|
||||
Brief->Kind = "ParagraphComment";
|
||||
Brief->Kind = CommentKind::CK_ParagraphComment;
|
||||
Brief->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Brief->Children.back()->Kind = "TextComment";
|
||||
Brief->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Brief->Children.back()->Name = "ParagraphComment";
|
||||
Brief->Children.back()->Text = " Brief description.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Extended = Top.Children.back().get();
|
||||
Extended->Kind = "ParagraphComment";
|
||||
Extended->Kind = CommentKind::CK_ParagraphComment;
|
||||
Extended->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Extended->Children.back()->Kind = "TextComment";
|
||||
Extended->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Extended->Children.back()->Text = " Extended description that";
|
||||
Extended->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Extended->Children.back()->Kind = "TextComment";
|
||||
Extended->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Extended->Children.back()->Text = " continues onto the next line.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Entities = Top.Children.back().get();
|
||||
Entities->Kind = "ParagraphComment";
|
||||
Entities->Kind = CommentKind::CK_ParagraphComment;
|
||||
Entities->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Entities->Children.back()->Kind = "TextComment";
|
||||
Entities->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Entities->Children.back()->Name = "ParagraphComment";
|
||||
Entities->Children.back()->Text =
|
||||
" Comment with html entities: &, <, >, \", \'.";
|
||||
|
||||
@@ -218,103 +218,105 @@ TEST(MDGeneratorTest, emitCommentMD) {
|
||||
I.Access = AccessSpecifier::AS_none;
|
||||
|
||||
CommentInfo Top;
|
||||
Top.Kind = "FullComment";
|
||||
Top.Kind = CommentKind::CK_FullComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *BlankLine = Top.Children.back().get();
|
||||
BlankLine->Kind = "ParagraphComment";
|
||||
BlankLine->Kind = CommentKind::CK_ParagraphComment;
|
||||
BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
BlankLine->Children.back()->Kind = "TextComment";
|
||||
BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Brief = Top.Children.back().get();
|
||||
Brief->Kind = "ParagraphComment";
|
||||
Brief->Kind = CommentKind::CK_ParagraphComment;
|
||||
Brief->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Brief->Children.back()->Kind = "TextComment";
|
||||
Brief->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Brief->Children.back()->Name = "ParagraphComment";
|
||||
Brief->Children.back()->Text = " Brief description.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Extended = Top.Children.back().get();
|
||||
Extended->Kind = "ParagraphComment";
|
||||
Extended->Kind = CommentKind::CK_ParagraphComment;
|
||||
Extended->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Extended->Children.back()->Kind = "TextComment";
|
||||
Extended->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Extended->Children.back()->Text = " Extended description that";
|
||||
Extended->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Extended->Children.back()->Kind = "TextComment";
|
||||
Extended->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Extended->Children.back()->Text = " continues onto the next line.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *HTML = Top.Children.back().get();
|
||||
HTML->Kind = "ParagraphComment";
|
||||
HTML->Kind = CommentKind::CK_ParagraphComment;
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "TextComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "HTMLStartTagComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
|
||||
HTML->Children.back()->Name = "ul";
|
||||
HTML->Children.back()->AttrKeys.emplace_back("class");
|
||||
HTML->Children.back()->AttrValues.emplace_back("test");
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "HTMLStartTagComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
|
||||
HTML->Children.back()->Name = "li";
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "TextComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
HTML->Children.back()->Text = " Testing.";
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "HTMLEndTagComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_HTMLEndTagComment;
|
||||
HTML->Children.back()->Name = "ul";
|
||||
HTML->Children.back()->SelfClosing = true;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Verbatim = Top.Children.back().get();
|
||||
Verbatim->Kind = "VerbatimBlockComment";
|
||||
Verbatim->Kind = CommentKind::CK_VerbatimBlockComment;
|
||||
Verbatim->Name = "verbatim";
|
||||
Verbatim->CloseName = "endverbatim";
|
||||
Verbatim->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Verbatim->Children.back()->Kind = "VerbatimBlockLineComment";
|
||||
Verbatim->Children.back()->Kind = CommentKind::CK_VerbatimBlockLineComment;
|
||||
Verbatim->Children.back()->Text = " The description continues.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *ParamOut = Top.Children.back().get();
|
||||
ParamOut->Kind = "ParamCommandComment";
|
||||
ParamOut->Kind = CommentKind::CK_ParamCommandComment;
|
||||
ParamOut->Direction = "[out]";
|
||||
ParamOut->ParamName = "I";
|
||||
ParamOut->Explicit = true;
|
||||
ParamOut->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
ParamOut->Children.back()->Kind = "ParagraphComment";
|
||||
ParamOut->Children.back()->Kind = CommentKind::CK_ParagraphComment;
|
||||
ParamOut->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamOut->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamOut->Children.back()->Children.back()->Kind =
|
||||
CommentKind::CK_TextComment;
|
||||
ParamOut->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamOut->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamOut->Children.back()->Children.back()->Kind =
|
||||
CommentKind::CK_TextComment;
|
||||
ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *ParamIn = Top.Children.back().get();
|
||||
ParamIn->Kind = "ParamCommandComment";
|
||||
ParamIn->Kind = CommentKind::CK_ParamCommandComment;
|
||||
ParamIn->Direction = "[in]";
|
||||
ParamIn->ParamName = "J";
|
||||
ParamIn->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
ParamIn->Children.back()->Kind = "ParagraphComment";
|
||||
ParamIn->Children.back()->Kind = CommentKind::CK_ParagraphComment;
|
||||
ParamIn->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamIn->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
|
||||
ParamIn->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamIn->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Return = Top.Children.back().get();
|
||||
Return->Kind = "BlockCommandComment";
|
||||
Return->Kind = CommentKind::CK_BlockCommandComment;
|
||||
Return->Name = "return";
|
||||
Return->Explicit = true;
|
||||
Return->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Return->Children.back()->Kind = "ParagraphComment";
|
||||
Return->Children.back()->Kind = CommentKind::CK_ParagraphComment;
|
||||
Return->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
Return->Children.back()->Children.back()->Kind = "TextComment";
|
||||
Return->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Return->Children.back()->Children.back()->Text = "void";
|
||||
|
||||
I.Description.emplace_back(std::move(Top));
|
||||
|
||||
@@ -166,11 +166,11 @@ TEST(MergeTest, mergeFunctionInfos) {
|
||||
|
||||
One.Description.emplace_back();
|
||||
auto *OneFullComment = &One.Description.back();
|
||||
OneFullComment->Kind = "FullComment";
|
||||
OneFullComment->Kind = CommentKind::CK_FullComment;
|
||||
auto OneParagraphComment = std::make_unique<CommentInfo>();
|
||||
OneParagraphComment->Kind = "ParagraphComment";
|
||||
OneParagraphComment->Kind = CommentKind::CK_ParagraphComment;
|
||||
auto OneTextComment = std::make_unique<CommentInfo>();
|
||||
OneTextComment->Kind = "TextComment";
|
||||
OneTextComment->Kind = CommentKind::CK_TextComment;
|
||||
OneTextComment->Text = "This is a text comment.";
|
||||
OneParagraphComment->Children.push_back(std::move(OneTextComment));
|
||||
OneFullComment->Children.push_back(std::move(OneParagraphComment));
|
||||
@@ -186,11 +186,11 @@ TEST(MergeTest, mergeFunctionInfos) {
|
||||
|
||||
Two.Description.emplace_back();
|
||||
auto *TwoFullComment = &Two.Description.back();
|
||||
TwoFullComment->Kind = "FullComment";
|
||||
TwoFullComment->Kind = CommentKind::CK_FullComment;
|
||||
auto TwoParagraphComment = std::make_unique<CommentInfo>();
|
||||
TwoParagraphComment->Kind = "ParagraphComment";
|
||||
TwoParagraphComment->Kind = CommentKind::CK_ParagraphComment;
|
||||
auto TwoTextComment = std::make_unique<CommentInfo>();
|
||||
TwoTextComment->Kind = "TextComment";
|
||||
TwoTextComment->Kind = CommentKind::CK_TextComment;
|
||||
TwoTextComment->Text = "This is a text comment.";
|
||||
TwoParagraphComment->Children.push_back(std::move(TwoTextComment));
|
||||
TwoFullComment->Children.push_back(std::move(TwoParagraphComment));
|
||||
@@ -213,11 +213,11 @@ TEST(MergeTest, mergeFunctionInfos) {
|
||||
|
||||
Expected->Description.emplace_back();
|
||||
auto *ExpectedFullComment = &Expected->Description.back();
|
||||
ExpectedFullComment->Kind = "FullComment";
|
||||
ExpectedFullComment->Kind = CommentKind::CK_FullComment;
|
||||
auto ExpectedParagraphComment = std::make_unique<CommentInfo>();
|
||||
ExpectedParagraphComment->Kind = "ParagraphComment";
|
||||
ExpectedParagraphComment->Kind = CommentKind::CK_ParagraphComment;
|
||||
auto ExpectedTextComment = std::make_unique<CommentInfo>();
|
||||
ExpectedTextComment->Kind = "TextComment";
|
||||
ExpectedTextComment->Kind = CommentKind::CK_TextComment;
|
||||
ExpectedTextComment->Text = "This is a text comment.";
|
||||
ExpectedParagraphComment->Children.push_back(std::move(ExpectedTextComment));
|
||||
ExpectedFullComment->Children.push_back(std::move(ExpectedParagraphComment));
|
||||
|
||||
@@ -91,12 +91,12 @@ TEST(YAMLGeneratorTest, emitRecordYAML) {
|
||||
|
||||
// Member documentation.
|
||||
CommentInfo TopComment;
|
||||
TopComment.Kind = "FullComment";
|
||||
TopComment.Kind = CommentKind::CK_FullComment;
|
||||
TopComment.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Brief = TopComment.Children.back().get();
|
||||
Brief->Kind = "ParagraphComment";
|
||||
Brief->Kind = CommentKind::CK_ParagraphComment;
|
||||
Brief->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Brief->Children.back()->Kind = "TextComment";
|
||||
Brief->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Brief->Children.back()->Name = "ParagraphComment";
|
||||
Brief->Children.back()->Text = "Value of the thing.";
|
||||
I.Members.back().Description.push_back(std::move(TopComment));
|
||||
@@ -150,11 +150,11 @@ Members:
|
||||
Name: 'X'
|
||||
Access: Private
|
||||
Description:
|
||||
- Kind: 'FullComment'
|
||||
- Kind: FullComment
|
||||
Children:
|
||||
- Kind: 'ParagraphComment'
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: 'TextComment'
|
||||
- Kind: TextComment
|
||||
Text: 'Value of the thing.'
|
||||
Name: 'ParagraphComment'
|
||||
Bases:
|
||||
@@ -375,103 +375,105 @@ TEST(YAMLGeneratorTest, emitCommentYAML) {
|
||||
I.Access = AccessSpecifier::AS_none;
|
||||
|
||||
CommentInfo Top;
|
||||
Top.Kind = "FullComment";
|
||||
Top.Kind = CommentKind::CK_FullComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *BlankLine = Top.Children.back().get();
|
||||
BlankLine->Kind = "ParagraphComment";
|
||||
BlankLine->Kind = CommentKind::CK_ParagraphComment;
|
||||
BlankLine->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
BlankLine->Children.back()->Kind = "TextComment";
|
||||
BlankLine->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Brief = Top.Children.back().get();
|
||||
Brief->Kind = "ParagraphComment";
|
||||
Brief->Kind = CommentKind::CK_ParagraphComment;
|
||||
Brief->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Brief->Children.back()->Kind = "TextComment";
|
||||
Brief->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Brief->Children.back()->Name = "ParagraphComment";
|
||||
Brief->Children.back()->Text = " Brief description.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Extended = Top.Children.back().get();
|
||||
Extended->Kind = "ParagraphComment";
|
||||
Extended->Kind = CommentKind::CK_ParagraphComment;
|
||||
Extended->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Extended->Children.back()->Kind = "TextComment";
|
||||
Extended->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Extended->Children.back()->Text = " Extended description that";
|
||||
Extended->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Extended->Children.back()->Kind = "TextComment";
|
||||
Extended->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Extended->Children.back()->Text = " continues onto the next line.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *HTML = Top.Children.back().get();
|
||||
HTML->Kind = "ParagraphComment";
|
||||
HTML->Kind = CommentKind::CK_ParagraphComment;
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "TextComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "HTMLStartTagComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
|
||||
HTML->Children.back()->Name = "ul";
|
||||
HTML->Children.back()->AttrKeys.emplace_back("class");
|
||||
HTML->Children.back()->AttrValues.emplace_back("test");
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "HTMLStartTagComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_HTMLStartTagComment;
|
||||
HTML->Children.back()->Name = "li";
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "TextComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
HTML->Children.back()->Text = " Testing.";
|
||||
HTML->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
HTML->Children.back()->Kind = "HTMLEndTagComment";
|
||||
HTML->Children.back()->Kind = CommentKind::CK_HTMLEndTagComment;
|
||||
HTML->Children.back()->Name = "ul";
|
||||
HTML->Children.back()->SelfClosing = true;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Verbatim = Top.Children.back().get();
|
||||
Verbatim->Kind = "VerbatimBlockComment";
|
||||
Verbatim->Kind = CommentKind::CK_VerbatimBlockComment;
|
||||
Verbatim->Name = "verbatim";
|
||||
Verbatim->CloseName = "endverbatim";
|
||||
Verbatim->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Verbatim->Children.back()->Kind = "VerbatimBlockLineComment";
|
||||
Verbatim->Children.back()->Kind = CommentKind::CK_VerbatimBlockLineComment;
|
||||
Verbatim->Children.back()->Text = " The description continues.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *ParamOut = Top.Children.back().get();
|
||||
ParamOut->Kind = "ParamCommandComment";
|
||||
ParamOut->Kind = CommentKind::CK_ParamCommandComment;
|
||||
ParamOut->Direction = "[out]";
|
||||
ParamOut->ParamName = "I";
|
||||
ParamOut->Explicit = true;
|
||||
ParamOut->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
ParamOut->Children.back()->Kind = "ParagraphComment";
|
||||
ParamOut->Children.back()->Kind = CommentKind::CK_ParagraphComment;
|
||||
ParamOut->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamOut->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamOut->Children.back()->Children.back()->Kind =
|
||||
CommentKind::CK_TextComment;
|
||||
ParamOut->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamOut->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamOut->Children.back()->Children.back()->Kind =
|
||||
CommentKind::CK_TextComment;
|
||||
ParamOut->Children.back()->Children.back()->Text = " is a parameter.";
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *ParamIn = Top.Children.back().get();
|
||||
ParamIn->Kind = "ParamCommandComment";
|
||||
ParamIn->Kind = CommentKind::CK_ParamCommandComment;
|
||||
ParamIn->Direction = "[in]";
|
||||
ParamIn->ParamName = "J";
|
||||
ParamIn->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
ParamIn->Children.back()->Kind = "ParagraphComment";
|
||||
ParamIn->Children.back()->Kind = CommentKind::CK_ParagraphComment;
|
||||
ParamIn->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamIn->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
ParamIn->Children.back()->Children.back()->Text = " is a parameter.";
|
||||
ParamIn->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
ParamIn->Children.back()->Children.back()->Kind = "TextComment";
|
||||
ParamIn->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
|
||||
Top.Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
CommentInfo *Return = Top.Children.back().get();
|
||||
Return->Kind = "BlockCommandComment";
|
||||
Return->Kind = CommentKind::CK_BlockCommandComment;
|
||||
Return->Name = "return";
|
||||
Return->Explicit = true;
|
||||
Return->Children.emplace_back(std::make_unique<CommentInfo>());
|
||||
Return->Children.back()->Kind = "ParagraphComment";
|
||||
Return->Children.back()->Kind = CommentKind::CK_ParagraphComment;
|
||||
Return->Children.back()->Children.emplace_back(
|
||||
std::make_unique<CommentInfo>());
|
||||
Return->Children.back()->Children.back()->Kind = "TextComment";
|
||||
Return->Children.back()->Children.back()->Kind = CommentKind::CK_TextComment;
|
||||
Return->Children.back()->Children.back()->Text = "void";
|
||||
|
||||
I.Description.emplace_back(std::move(Top));
|
||||
@@ -487,70 +489,70 @@ TEST(YAMLGeneratorTest, emitCommentYAML) {
|
||||
USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'f'
|
||||
Description:
|
||||
- Kind: 'FullComment'
|
||||
- Kind: FullComment
|
||||
Children:
|
||||
- Kind: 'ParagraphComment'
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: 'TextComment'
|
||||
- Kind: 'ParagraphComment'
|
||||
- Kind: TextComment
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: 'TextComment'
|
||||
- Kind: TextComment
|
||||
Text: ' Brief description.'
|
||||
Name: 'ParagraphComment'
|
||||
- Kind: 'ParagraphComment'
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: 'TextComment'
|
||||
- Kind: TextComment
|
||||
Text: ' Extended description that'
|
||||
- Kind: 'TextComment'
|
||||
- Kind: TextComment
|
||||
Text: ' continues onto the next line.'
|
||||
- Kind: 'ParagraphComment'
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: 'TextComment'
|
||||
- Kind: 'HTMLStartTagComment'
|
||||
- Kind: TextComment
|
||||
- Kind: HTMLStartTagComment
|
||||
Name: 'ul'
|
||||
AttrKeys:
|
||||
- 'class'
|
||||
AttrValues:
|
||||
- 'test'
|
||||
- Kind: 'HTMLStartTagComment'
|
||||
- Kind: HTMLStartTagComment
|
||||
Name: 'li'
|
||||
- Kind: 'TextComment'
|
||||
- Kind: TextComment
|
||||
Text: ' Testing.'
|
||||
- Kind: 'HTMLEndTagComment'
|
||||
- Kind: HTMLEndTagComment
|
||||
Name: 'ul'
|
||||
SelfClosing: true
|
||||
- Kind: 'VerbatimBlockComment'
|
||||
- Kind: VerbatimBlockComment
|
||||
Name: 'verbatim'
|
||||
CloseName: 'endverbatim'
|
||||
Children:
|
||||
- Kind: 'VerbatimBlockLineComment'
|
||||
- Kind: VerbatimBlockLineComment
|
||||
Text: ' The description continues.'
|
||||
- Kind: 'ParamCommandComment'
|
||||
- Kind: ParamCommandComment
|
||||
Direction: '[out]'
|
||||
ParamName: 'I'
|
||||
Explicit: true
|
||||
Children:
|
||||
- Kind: 'ParagraphComment'
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: 'TextComment'
|
||||
- Kind: 'TextComment'
|
||||
- Kind: TextComment
|
||||
- Kind: TextComment
|
||||
Text: ' is a parameter.'
|
||||
- Kind: 'ParamCommandComment'
|
||||
- Kind: ParamCommandComment
|
||||
Direction: '[in]'
|
||||
ParamName: 'J'
|
||||
Children:
|
||||
- Kind: 'ParagraphComment'
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: 'TextComment'
|
||||
- Kind: TextComment
|
||||
Text: ' is a parameter.'
|
||||
- Kind: 'TextComment'
|
||||
- Kind: 'BlockCommandComment'
|
||||
- Kind: TextComment
|
||||
- Kind: BlockCommandComment
|
||||
Name: 'return'
|
||||
Explicit: true
|
||||
Children:
|
||||
- Kind: 'ParagraphComment'
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: 'TextComment'
|
||||
- Kind: TextComment
|
||||
Text: 'void'
|
||||
DefLocation:
|
||||
LineNumber: 10
|
||||
|
||||
Reference in New Issue
Block a user