[clang-doc] Remove the YAML generator (#209350)
The original intent of the YAML generator was to package the documentation information in a structured and reusable way. It has been superseded by the JSON generator.
This commit is contained in:
1 parent
6de51be4f6
commit
1bd46015ea
14 files changed
+6
-1464
No files matched your search
@@ -15,7 +15,6 @@ add_clang_library(clangDoc STATIC
|
||||
MDGenerator.cpp
|
||||
Representation.cpp
|
||||
Serialize.cpp
|
||||
YAMLGenerator.cpp
|
||||
JSONGenerator.cpp
|
||||
|
||||
DEPENDS
|
||||
|
||||
@@ -248,7 +248,6 @@ void Generator::addInfoToIndex(Index &Idx, const doc::Info *Info) {
|
||||
|
||||
// This anchor is used to force the linker to link in the generated object file
|
||||
// and thus register the generators.
|
||||
[[maybe_unused]] static int YAMLGeneratorAnchorDest = YAMLGeneratorAnchorSource;
|
||||
[[maybe_unused]] static int MDGeneratorAnchorDest = MDGeneratorAnchorSource;
|
||||
[[maybe_unused]] static int HTMLGeneratorAnchorDest = HTMLGeneratorAnchorSource;
|
||||
[[maybe_unused]] static int JSONGeneratorAnchorDest = JSONGeneratorAnchorSource;
|
||||
|
||||
@@ -140,7 +140,6 @@ struct MustacheGenerator : public Generator {
|
||||
|
||||
// This anchor is used to force the linker to link in the generated object file
|
||||
// and thus register the generators.
|
||||
extern volatile int YAMLGeneratorAnchorSource;
|
||||
extern volatile int MDGeneratorAnchorSource;
|
||||
extern volatile int HTMLGeneratorAnchorSource;
|
||||
extern volatile int JSONGeneratorAnchorSource;
|
||||
|
||||
@@ -225,7 +225,7 @@ enum class CommentKind {
|
||||
CK_Unknown
|
||||
};
|
||||
|
||||
enum OutputFormatTy { md, yaml, html, json };
|
||||
enum OutputFormatTy { md, html, json };
|
||||
|
||||
CommentKind stringToCommentKind(llvm::StringRef KindStr);
|
||||
llvm::StringRef commentKindToString(CommentKind Kind);
|
||||
|
||||
@@ -1,585 +0,0 @@
|
||||
//===-- YAMLGenerator.cpp - ClangDoc YAML -----------------------*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Implementation of the YAML generator, converting decl info into YAML output.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Generators.h"
|
||||
#include "Representation.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Support/YAMLTraits.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <optional>
|
||||
|
||||
using namespace clang::doc;
|
||||
|
||||
// These define YAML traits for decoding the listed values within a vector.
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(FieldTypeInfo)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(MemberTypeInfo)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(Reference)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(Location)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(CommentInfo)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionInfo)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(EnumInfo)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(EnumValueInfo)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(TemplateParamInfo)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(TypedefInfo)
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(BaseRecordInfo)
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace yaml {
|
||||
|
||||
// Provide SequenceTraits for ArrayRef<T*> since YAMLTraits only provides it for
|
||||
// MutableArrayRef
|
||||
template <typename T> struct SequenceTraits<ArrayRef<T *>> {
|
||||
static size_t size(IO &io, ArrayRef<T *> &seq) { return seq.size(); }
|
||||
static T *&element(IO &io, ArrayRef<T *> &seq, size_t index) {
|
||||
// ArrayRef is not mutable, but YAML output only reads the value.
|
||||
return const_cast<T *&>(seq[index]);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct SequenceTraits<llvm::simple_ilist<T>> {
|
||||
static size_t size(IO &io, llvm::simple_ilist<T> &seq) { return seq.size(); }
|
||||
static T &element(IO &io, llvm::simple_ilist<T> &seq, size_t index) {
|
||||
return *std::next(seq.begin(), index);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct SequenceTraits<clang::doc::DocList<T>> {
|
||||
static size_t size(IO &io, clang::doc::DocList<T> &seq) { return seq.size(); }
|
||||
static T &element(IO &io, clang::doc::DocList<T> &seq, size_t index) {
|
||||
return *(std::next(seq.begin(), index));
|
||||
}
|
||||
};
|
||||
|
||||
// Map pointers to the value mappings as clang-doc only does output
|
||||
// serialization.
|
||||
template <typename T> struct PointerMappingTraits {
|
||||
static void mapping(IO &IO, T *&Val) {
|
||||
if (Val)
|
||||
MappingTraits<T>::mapping(IO, *Val);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct MappingTraits<clang::doc::Reference *>
|
||||
: PointerMappingTraits<clang::doc::Reference> {};
|
||||
template <>
|
||||
struct MappingTraits<clang::doc::CommentInfo *>
|
||||
: PointerMappingTraits<clang::doc::CommentInfo> {};
|
||||
template <>
|
||||
struct MappingTraits<clang::doc::FunctionInfo *>
|
||||
: PointerMappingTraits<clang::doc::FunctionInfo> {};
|
||||
template <>
|
||||
struct MappingTraits<clang::doc::EnumInfo *>
|
||||
: PointerMappingTraits<clang::doc::EnumInfo> {};
|
||||
template <>
|
||||
struct MappingTraits<clang::doc::TemplateParamInfo *>
|
||||
: PointerMappingTraits<clang::doc::TemplateParamInfo> {};
|
||||
|
||||
template <typename T> struct SequenceTraits<ArrayRef<T>> {
|
||||
static size_t size(IO &io, llvm::ArrayRef<T> &seq) { return seq.size(); }
|
||||
static T &element(IO &io, llvm::ArrayRef<T> &seq, size_t index) {
|
||||
return const_cast<T &>(seq[index]);
|
||||
}
|
||||
};
|
||||
|
||||
// Enumerations to YAML output.
|
||||
|
||||
template <> struct ScalarEnumerationTraits<clang::AccessSpecifier> {
|
||||
static void enumeration(IO &IO, clang::AccessSpecifier &Value) {
|
||||
IO.enumCase(Value, "Public", clang::AccessSpecifier::AS_public);
|
||||
IO.enumCase(Value, "Protected", clang::AccessSpecifier::AS_protected);
|
||||
IO.enumCase(Value, "Private", clang::AccessSpecifier::AS_private);
|
||||
IO.enumCase(Value, "None", clang::AccessSpecifier::AS_none);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct ScalarEnumerationTraits<clang::TagTypeKind> {
|
||||
static void enumeration(IO &IO, clang::TagTypeKind &Value) {
|
||||
IO.enumCase(Value, "Struct", clang::TagTypeKind::Struct);
|
||||
IO.enumCase(Value, "Interface", clang::TagTypeKind::Interface);
|
||||
IO.enumCase(Value, "Union", clang::TagTypeKind::Union);
|
||||
IO.enumCase(Value, "Class", clang::TagTypeKind::Class);
|
||||
IO.enumCase(Value, "Enum", clang::TagTypeKind::Enum);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct ScalarEnumerationTraits<InfoType> {
|
||||
static void enumeration(IO &IO, InfoType &Value) {
|
||||
IO.enumCase(Value, "Namespace", InfoType::IT_namespace);
|
||||
IO.enumCase(Value, "Record", InfoType::IT_record);
|
||||
IO.enumCase(Value, "Function", InfoType::IT_function);
|
||||
IO.enumCase(Value, "Enum", InfoType::IT_enum);
|
||||
IO.enumCase(Value, "Default", InfoType::IT_default);
|
||||
}
|
||||
};
|
||||
|
||||
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 <> struct ScalarTraits<SymbolID> {
|
||||
|
||||
static void output(const SymbolID &S, void *, llvm::raw_ostream &OS) {
|
||||
OS << toHex(toStringRef(S));
|
||||
}
|
||||
|
||||
static StringRef input(StringRef Scalar, void *, SymbolID &Value) {
|
||||
if (Scalar.size() != 40)
|
||||
return "Error: Incorrect scalar size for USR.";
|
||||
Value = stringToSymbol(Scalar);
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
static SymbolID stringToSymbol(llvm::StringRef Value) {
|
||||
SymbolID USR;
|
||||
std::string HexString = fromHex(Value);
|
||||
llvm::copy(HexString, USR.begin());
|
||||
return SymbolID(USR);
|
||||
}
|
||||
|
||||
static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
|
||||
};
|
||||
|
||||
/// A wrapper for StringRef to force YAML traits to single-quote the string.
|
||||
struct QuotedString {
|
||||
StringRef Ref;
|
||||
QuotedString() = default;
|
||||
explicit QuotedString(StringRef R) : Ref(R) {}
|
||||
explicit operator StringRef() const { return Ref; }
|
||||
bool operator==(const QuotedString &Other) const { return Ref == Other.Ref; }
|
||||
};
|
||||
|
||||
template <> struct ScalarTraits<QuotedString> {
|
||||
static void output(const QuotedString &S, void *, llvm::raw_ostream &OS) {
|
||||
OS << S.Ref;
|
||||
}
|
||||
static StringRef input(StringRef Scalar, void *, QuotedString &Value) {
|
||||
Value.Ref = Scalar;
|
||||
return StringRef();
|
||||
}
|
||||
static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
|
||||
};
|
||||
} // end namespace yaml
|
||||
} // end namespace llvm
|
||||
|
||||
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::QuotedString)
|
||||
|
||||
namespace llvm {
|
||||
namespace yaml {
|
||||
|
||||
// Helper functions to map infos to YAML.
|
||||
|
||||
static void typeInfoMapping(IO &IO, TypeInfo &I) {
|
||||
IO.mapOptional("Type", I.Type, Reference());
|
||||
}
|
||||
|
||||
static void fieldTypeInfoMapping(IO &IO, FieldTypeInfo &I) {
|
||||
typeInfoMapping(IO, I);
|
||||
|
||||
QuotedString QName(I.Name);
|
||||
IO.mapOptional("Name", QName, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.Name = QName.Ref;
|
||||
|
||||
QuotedString QDefault(I.DefaultValue);
|
||||
IO.mapOptional("DefaultValue", QDefault, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.DefaultValue = QDefault.Ref;
|
||||
}
|
||||
|
||||
static void infoMapping(IO &IO, Info &I) {
|
||||
IO.mapRequired("USR", I.USR);
|
||||
|
||||
QuotedString QName(I.Name);
|
||||
IO.mapOptional("Name", QName, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.Name = QName.Ref;
|
||||
|
||||
QuotedString QPath(I.Path);
|
||||
IO.mapOptional("Path", QPath, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.Path = QPath.Ref;
|
||||
|
||||
IO.mapOptional("Namespace", I.Namespace, llvm::SmallVector<Reference, 4>());
|
||||
IO.mapOptional("Description", I.Description);
|
||||
}
|
||||
|
||||
static void symbolInfoMapping(IO &IO, SymbolInfo &I) {
|
||||
infoMapping(IO, I);
|
||||
IO.mapOptional("DefLocation", I.DefLoc, std::optional<Location>());
|
||||
IO.mapOptional("Location", I.Loc);
|
||||
}
|
||||
|
||||
static void recordInfoMapping(IO &IO, RecordInfo &I) {
|
||||
symbolInfoMapping(IO, I);
|
||||
IO.mapOptional("TagType", I.TagType);
|
||||
IO.mapOptional("IsTypeDef", I.IsTypeDef, false);
|
||||
IO.mapOptional("Members", I.Members);
|
||||
IO.mapOptional("Bases", I.Bases);
|
||||
IO.mapOptional("Parents", I.Parents, SmallVector<Reference, 4>());
|
||||
IO.mapOptional("VirtualParents", I.VirtualParents,
|
||||
llvm::SmallVector<Reference, 4>());
|
||||
IO.mapOptional("ChildRecords", I.Children.Records);
|
||||
IO.mapOptional("ChildFunctions", I.Children.Functions);
|
||||
IO.mapOptional("ChildEnums", I.Children.Enums);
|
||||
IO.mapOptional("ChildTypedefs", I.Children.Typedefs);
|
||||
IO.mapOptional("Template", I.Template);
|
||||
}
|
||||
|
||||
static void commentInfoMapping(IO &IO, CommentInfo &I) {
|
||||
IO.mapOptional("Kind", I.Kind, CommentKind::CK_Unknown);
|
||||
|
||||
QuotedString QText(I.Text);
|
||||
IO.mapOptional("Text", QText, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.Text = QText.Ref;
|
||||
|
||||
QuotedString QName(I.Name);
|
||||
IO.mapOptional("Name", QName, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.Name = QName.Ref;
|
||||
|
||||
QuotedString QDirection(I.Direction);
|
||||
IO.mapOptional("Direction", QDirection, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.Direction = QDirection.Ref;
|
||||
|
||||
QuotedString QParamName(I.ParamName);
|
||||
IO.mapOptional("ParamName", QParamName, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.ParamName = QParamName.Ref;
|
||||
|
||||
QuotedString QCloseName(I.CloseName);
|
||||
IO.mapOptional("CloseName", QCloseName, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.CloseName = QCloseName.Ref;
|
||||
|
||||
IO.mapOptional("SelfClosing", I.SelfClosing, false);
|
||||
IO.mapOptional("Explicit", I.Explicit, false);
|
||||
|
||||
std::vector<QuotedString> QArgs;
|
||||
if (IO.outputting()) {
|
||||
for (auto &S : I.Args)
|
||||
QArgs.push_back(QuotedString(S));
|
||||
}
|
||||
IO.mapOptional("Args", QArgs, std::vector<QuotedString>());
|
||||
|
||||
std::vector<QuotedString> QAttrKeys;
|
||||
if (IO.outputting()) {
|
||||
for (auto &S : I.AttrKeys)
|
||||
QAttrKeys.push_back(QuotedString(S));
|
||||
}
|
||||
IO.mapOptional("AttrKeys", QAttrKeys, std::vector<QuotedString>());
|
||||
|
||||
std::vector<QuotedString> QAttrValues;
|
||||
if (IO.outputting()) {
|
||||
for (auto &S : I.AttrValues)
|
||||
QAttrValues.push_back(QuotedString(S));
|
||||
}
|
||||
IO.mapOptional("AttrValues", QAttrValues, std::vector<QuotedString>());
|
||||
|
||||
IO.mapOptional("Children", I.Children);
|
||||
}
|
||||
|
||||
// Template specialization to YAML traits for Infos.
|
||||
|
||||
template <> struct MappingTraits<Location> {
|
||||
static void mapping(IO &IO, Location &Loc) {
|
||||
IO.mapOptional("LineNumber", Loc.StartLineNumber, 0);
|
||||
|
||||
QuotedString QFilename(Loc.Filename);
|
||||
IO.mapOptional("Filename", QFilename, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
Loc.Filename = QFilename.Ref;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<Reference> {
|
||||
static void mapping(IO &IO, Reference &Ref) {
|
||||
IO.mapOptional("Type", Ref.RefType, InfoType::IT_default);
|
||||
|
||||
QuotedString QName(Ref.Name);
|
||||
IO.mapOptional("Name", QName, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
Ref.Name = QName.Ref;
|
||||
|
||||
QuotedString QQualName(Ref.QualName);
|
||||
IO.mapOptional("QualName", QQualName, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
Ref.QualName = QQualName.Ref;
|
||||
|
||||
IO.mapOptional("USR", Ref.USR, SymbolID());
|
||||
|
||||
QuotedString QPath(Ref.Path);
|
||||
IO.mapOptional("Path", QPath, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
Ref.Path = QPath.Ref;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<TypeInfo> {
|
||||
static void mapping(IO &IO, TypeInfo &I) { typeInfoMapping(IO, I); }
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<FieldTypeInfo> {
|
||||
static void mapping(IO &IO, FieldTypeInfo &I) {
|
||||
typeInfoMapping(IO, I);
|
||||
|
||||
QuotedString QName(I.Name);
|
||||
IO.mapOptional("Name", QName, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.Name = QName.Ref;
|
||||
|
||||
QuotedString QDefault(I.DefaultValue);
|
||||
IO.mapOptional("DefaultValue", QDefault, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.DefaultValue = QDefault.Ref;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<MemberTypeInfo> {
|
||||
static void mapping(IO &IO, MemberTypeInfo &I) {
|
||||
fieldTypeInfoMapping(IO, I);
|
||||
// clang::AccessSpecifier::AS_none is used as the default here because it's
|
||||
// the AS that shouldn't be part of the output. Even though AS_public is the
|
||||
// default in the struct, it should be displayed in the YAML output.
|
||||
IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none);
|
||||
IO.mapOptional("Description", I.Description);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<NamespaceInfo> {
|
||||
static void mapping(IO &IO, NamespaceInfo &I) {
|
||||
infoMapping(IO, I);
|
||||
std::vector<Reference> TempNamespaces;
|
||||
for (const auto &N : I.Children.Namespaces)
|
||||
TempNamespaces.push_back(N);
|
||||
IO.mapOptional("ChildNamespaces", TempNamespaces, std::vector<Reference>());
|
||||
IO.mapOptional("ChildRecords", I.Children.Records);
|
||||
IO.mapOptional("ChildFunctions", I.Children.Functions);
|
||||
IO.mapOptional("ChildEnums", I.Children.Enums);
|
||||
IO.mapOptional("ChildTypedefs", I.Children.Typedefs);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<RecordInfo> {
|
||||
static void mapping(IO &IO, RecordInfo &I) { recordInfoMapping(IO, I); }
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<BaseRecordInfo> {
|
||||
static void mapping(IO &IO, BaseRecordInfo &I) {
|
||||
recordInfoMapping(IO, I);
|
||||
IO.mapOptional("IsVirtual", I.IsVirtual, false);
|
||||
// clang::AccessSpecifier::AS_none is used as the default here because it's
|
||||
// the AS that shouldn't be part of the output. Even though AS_public is the
|
||||
// default in the struct, it should be displayed in the YAML output.
|
||||
IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none);
|
||||
IO.mapOptional("IsParent", I.IsParent, false);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<EnumValueInfo> {
|
||||
static void mapping(IO &IO, EnumValueInfo &I) {
|
||||
QuotedString QName(I.Name);
|
||||
IO.mapOptional("Name", QName, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.Name = QName.Ref;
|
||||
|
||||
QuotedString QValue(I.Value);
|
||||
IO.mapOptional("Value", QValue, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.Value = QValue.Ref;
|
||||
|
||||
QuotedString QExpr(I.ValueExpr);
|
||||
IO.mapOptional("Expr", QExpr, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.ValueExpr = QExpr.Ref;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<EnumInfo> {
|
||||
static void mapping(IO &IO, EnumInfo &I) {
|
||||
symbolInfoMapping(IO, I);
|
||||
IO.mapOptional("Scoped", I.Scoped, false);
|
||||
IO.mapOptional("BaseType", I.BaseType);
|
||||
IO.mapOptional("Members", I.Members);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<TypedefInfo> {
|
||||
static void mapping(IO &IO, TypedefInfo &I) {
|
||||
symbolInfoMapping(IO, I);
|
||||
IO.mapOptional("Underlying", I.Underlying.Type);
|
||||
IO.mapOptional("IsUsing", I.IsUsing, false);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<FunctionInfo> {
|
||||
static void mapping(IO &IO, FunctionInfo &I) {
|
||||
symbolInfoMapping(IO, I);
|
||||
IO.mapOptional("IsMethod", I.IsMethod, false);
|
||||
IO.mapOptional("Parent", I.Parent, Reference());
|
||||
IO.mapOptional("Params", I.Params);
|
||||
IO.mapOptional("ReturnType", I.ReturnType);
|
||||
// clang::AccessSpecifier::AS_none is used as the default here because it's
|
||||
// the AS that shouldn't be part of the output. Even though AS_public is the
|
||||
// default in the struct, it should be displayed in the YAML output.
|
||||
IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none);
|
||||
IO.mapOptional("Template", I.Template);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<TemplateParamInfo> {
|
||||
static void mapping(IO &IO, TemplateParamInfo &I) {
|
||||
QuotedString QContents(I.Contents);
|
||||
IO.mapOptional("Contents", QContents, QuotedString(StringRef()));
|
||||
if (!IO.outputting())
|
||||
I.Contents = QContents.Ref;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<TemplateSpecializationInfo> {
|
||||
static void mapping(IO &IO, TemplateSpecializationInfo &I) {
|
||||
IO.mapOptional("SpecializationOf", I.SpecializationOf);
|
||||
IO.mapOptional("Params", I.Params);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<TemplateInfo> {
|
||||
static void mapping(IO &IO, TemplateInfo &I) {
|
||||
IO.mapOptional("Params", I.Params);
|
||||
IO.mapOptional("Specialization", I.Specialization,
|
||||
std::optional<TemplateSpecializationInfo>());
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct MappingTraits<CommentInfo> {
|
||||
static void mapping(IO &IO, CommentInfo &I) { commentInfoMapping(IO, I); }
|
||||
};
|
||||
|
||||
} // end namespace yaml
|
||||
} // end namespace llvm
|
||||
|
||||
namespace clang {
|
||||
namespace doc {
|
||||
|
||||
/// Generator for YAML documentation.
|
||||
class YAMLGenerator : public Generator {
|
||||
public:
|
||||
static const char *Format;
|
||||
|
||||
llvm::Error generateDocumentation(StringRef RootDir,
|
||||
llvm::StringMap<doc::Info *> Infos,
|
||||
const ClangDocContext &CDCtx,
|
||||
std::string DirName) override;
|
||||
llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS,
|
||||
const ClangDocContext &CDCtx) override;
|
||||
};
|
||||
|
||||
const char *YAMLGenerator::Format = "yaml";
|
||||
|
||||
llvm::Error YAMLGenerator::generateDocumentation(
|
||||
StringRef RootDir, llvm::StringMap<doc::Info *> Infos,
|
||||
const ClangDocContext &CDCtx, std::string DirName) {
|
||||
for (const auto &Group : Infos) {
|
||||
doc::Info *Info = Group.getValue();
|
||||
|
||||
// Output file names according to the USR except the global namesapce.
|
||||
// Anonymous namespaces are taken care of in serialization, so here we can
|
||||
// safely assume an unnamed namespace is the global one.
|
||||
llvm::SmallString<128> Path;
|
||||
llvm::sys::path::native(RootDir, Path);
|
||||
if (Info->IT == InfoType::IT_namespace && Info->Name.empty()) {
|
||||
llvm::sys::path::append(Path, "index.yaml");
|
||||
} else {
|
||||
llvm::sys::path::append(Path, Group.getKey() + ".yaml");
|
||||
}
|
||||
|
||||
std::error_code FileErr;
|
||||
llvm::raw_fd_ostream InfoOS(Path, FileErr, llvm::sys::fs::OF_Text);
|
||||
if (FileErr) {
|
||||
return llvm::createStringError(FileErr, "Error opening file '%s'",
|
||||
Path.c_str());
|
||||
}
|
||||
|
||||
if (llvm::Error Err = generateDocForInfo(Info, InfoOS, CDCtx)) {
|
||||
return Err;
|
||||
}
|
||||
}
|
||||
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
|
||||
const ClangDocContext &CDCtx) {
|
||||
llvm::yaml::Output InfoYAML(OS);
|
||||
switch (I->IT) {
|
||||
case InfoType::IT_namespace:
|
||||
InfoYAML << *cast<NamespaceInfo>(I);
|
||||
break;
|
||||
case InfoType::IT_record:
|
||||
InfoYAML << *cast<RecordInfo>(I);
|
||||
break;
|
||||
case InfoType::IT_enum:
|
||||
InfoYAML << *cast<EnumInfo>(I);
|
||||
break;
|
||||
case InfoType::IT_function:
|
||||
InfoYAML << *cast<FunctionInfo>(I);
|
||||
break;
|
||||
case InfoType::IT_typedef:
|
||||
InfoYAML << *cast<TypedefInfo>(I);
|
||||
break;
|
||||
case InfoType::IT_concept:
|
||||
case InfoType::IT_variable:
|
||||
case InfoType::IT_friend:
|
||||
break;
|
||||
case InfoType::IT_default:
|
||||
return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
||||
"unexpected InfoType");
|
||||
}
|
||||
return llvm::Error::success();
|
||||
}
|
||||
|
||||
static GeneratorRegistry::Add<YAMLGenerator> YAML(YAMLGenerator::Format,
|
||||
"Generator for YAML output.");
|
||||
|
||||
// This anchor is used to force the linker to link in the generated object file
|
||||
// and thus register the generator.
|
||||
volatile int YAMLGeneratorAnchorSource = 0;
|
||||
|
||||
} // namespace doc
|
||||
} // namespace clang
|
||||
@@ -119,23 +119,19 @@ static llvm::cl::opt<bool>
|
||||
|
||||
static llvm::cl::opt<OutputFormatTy>
|
||||
FormatEnum("format", llvm::cl::desc("Format for outputted docs."),
|
||||
llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml",
|
||||
"Documentation in YAML format."),
|
||||
clEnumValN(OutputFormatTy::md, "md",
|
||||
llvm::cl::values(clEnumValN(OutputFormatTy::md, "md",
|
||||
"Documentation in MD format."),
|
||||
clEnumValN(OutputFormatTy::html, "html",
|
||||
"Documentation in HTML format."),
|
||||
clEnumValN(OutputFormatTy::json, "json",
|
||||
"Documentation in JSON format")),
|
||||
llvm::cl::init(OutputFormatTy::yaml),
|
||||
llvm::cl::init(OutputFormatTy::json),
|
||||
llvm::cl::cat(ClangDocCategory));
|
||||
|
||||
static llvm::ExitOnError ExitOnErr;
|
||||
|
||||
static llvm::StringRef getFormatString() {
|
||||
switch (FormatEnum) {
|
||||
case OutputFormatTy::yaml:
|
||||
return "yaml";
|
||||
case OutputFormatTy::md:
|
||||
return "md";
|
||||
case OutputFormatTy::html:
|
||||
|
||||
@@ -135,6 +135,9 @@ Potentially Breaking Changes
|
||||
now uses the new Mustache-backed MD generator. It is possible that there are some
|
||||
regressions in MD output.
|
||||
|
||||
- Removed the :program:`clang-doc` YAML generator. Prefer the JSON generator to
|
||||
get documentation information in a reusable format.
|
||||
|
||||
Improvements to clangd
|
||||
----------------------
|
||||
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
// RUN: rm -rf %t
|
||||
// RUN: mkdir -p %t/yaml %t/md %t/md_mustache
|
||||
// RUN: clang-doc --doxygen --executor=standalone %S/../Inputs/builtin_types.cpp -output=%t/yaml
|
||||
// RUN: FileCheck %s < %t/yaml/index.yaml --check-prefix=YAML
|
||||
|
||||
// YAML: ---
|
||||
// YAML-NEXT: USR: '0000000000000000000000000000000000000000'
|
||||
// YAML-NEXT: ChildFunctions:
|
||||
|
||||
// YAML-NEXT: - USR: '88A104C263241E354ECF5B55B04AE8CEAD625B71'
|
||||
// YAML-NEXT: Name: 'b'
|
||||
// YAML-NEXT: Location:
|
||||
// YAML-NEXT: - LineNumber: 1
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'bool'
|
||||
// YAML-NEXT: QualName: 'bool'
|
||||
|
||||
// YAML-NEXT: - USR: 'EA3287837B3F175C8DB154406B4DAD2924F479B5'
|
||||
// YAML-NEXT: Name: 'c'
|
||||
// YAML-NEXT: Location:
|
||||
// YAML-NEXT: - LineNumber: 2
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'char'
|
||||
// YAML-NEXT: QualName: 'char'
|
||||
|
||||
// YAML-NEXT: - USR: '60A47E4696CEFC411AB2E1EEFA2DD914E2A7E450'
|
||||
// YAML-NEXT: Name: 'd'
|
||||
// YAML-NEXT: Location:
|
||||
// YAML-NEXT: - LineNumber: 3
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'double'
|
||||
// YAML-NEXT: QualName: 'double'
|
||||
|
||||
// YAML-NEXT: - USR: 'B3A9EC6BECD5869CF3ACDFB25153CFE6BBDD5EAB'
|
||||
// YAML-NEXT: Name: 'f'
|
||||
// YAML-NEXT: Location:
|
||||
// YAML-NEXT: - LineNumber: 4
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'float'
|
||||
// YAML-NEXT: QualName: 'float'
|
||||
|
||||
// YAML-NEXT: - USR: '307041280A81EB46F949A94AD52587C659FD801C'
|
||||
// YAML-NEXT: Name: 'i'
|
||||
// YAML-NEXT: Location:
|
||||
// YAML-NEXT: - LineNumber: 5
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'int'
|
||||
// YAML-NEXT: QualName: 'int'
|
||||
|
||||
// YAML-NEXT: - USR: 'A1CE9AB0064C412F857592E01332C641C1A06F37'
|
||||
// YAML-NEXT: Name: 'l'
|
||||
// YAML-NEXT: Location:
|
||||
// YAML-NEXT: - LineNumber: 6
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'long'
|
||||
// YAML-NEXT: QualName: 'long'
|
||||
|
||||
// YAML-NEXT: - USR: '5C2C44ED4825C066EF6ED796863586F343C8BCA9'
|
||||
// YAML-NEXT: Name: 'll'
|
||||
// YAML-NEXT: Location:
|
||||
// YAML-NEXT: - LineNumber: 7
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'long long'
|
||||
// YAML-NEXT: QualName: 'long long'
|
||||
|
||||
// YAML-NEXT: - USR: '412341570FD3AD2C3A1E9A1DE7B3C01C07BEACFE'
|
||||
// YAML-NEXT: Name: 's'
|
||||
// YAML-NEXT: Location:
|
||||
// YAML-NEXT: - LineNumber: 8
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'short'
|
||||
// YAML-NEXT: QualName: 'short'
|
||||
// YAML-NEXT: ...
|
||||
@@ -1,6 +0,0 @@
|
||||
// RUN: rm -rf %t && mkdir -p %t
|
||||
// RUN: clang-doc --output=%t --executor=standalone %S/../Inputs/conversion_function.cpp
|
||||
// RUN: find %t/ -regex ".*/[0-9A-F]*.yaml" -exec cat {} ";" | FileCheck %s --check-prefix=CHECK-YAML
|
||||
|
||||
// Output correct conversion names.
|
||||
// CHECK-YAML: Name: 'operator T'
|
||||
@@ -1,5 +0,0 @@
|
||||
// RUN: rm -rf %t && mkdir -p %t
|
||||
// RUN: echo "" > %t/compile_flags.txt
|
||||
// RUN: cp "%S/../Inputs/single-file-public.cpp" "%t/test.cpp"
|
||||
// RUN: clang-doc --doxygen --public --executor=standalone -p %t %t/test.cpp -output=%t/docs
|
||||
// This produces two files, index.yaml and one for the record named by its USR
|
||||
@@ -1,27 +0,0 @@
|
||||
// RUN: rm -rf %t && mkdir -p %t
|
||||
// RUN: echo "" > %t/compile_flags.txt
|
||||
// RUN: cp "%S/../Inputs/single-file.cpp" "%t/test.cpp"
|
||||
// RUN: clang-doc --doxygen --executor=standalone -p %t %t/test.cpp -output=%t/docs
|
||||
// RUN: FileCheck %s -input-file=%t/docs/index.yaml --check-prefix=CHECK
|
||||
|
||||
// CHECK: ---
|
||||
// CHECK-NEXT: USR: '{{([0-9A-F]{40})}}'
|
||||
// CHECK-NEXT: ChildFunctions:
|
||||
// CHECK-NEXT: - USR: '{{([0-9A-F]{40})}}'
|
||||
// CHECK-NEXT: Name: 'function'
|
||||
// CHECK-NEXT: DefLocation:
|
||||
// CHECK-NEXT: LineNumber: 3
|
||||
// CHECK-NEXT: Filename: '{{.*}}
|
||||
// CHECK-NEXT: Location:
|
||||
// CHECK-NEXT: - LineNumber: 1
|
||||
// CHECK-NEXT: Filename: '{{.*}}'
|
||||
// CHECK-NEXT: Params:
|
||||
// CHECK-NEXT: - Type:
|
||||
// CHECK-NEXT: Name: 'int'
|
||||
// CHECK-NEXT: QualName: 'int'
|
||||
// CHECK-NEXT: Name: 'x'
|
||||
// CHECK-NEXT: ReturnType:
|
||||
// CHECK-NEXT: Type:
|
||||
// CHECK-NEXT: Name: 'void'
|
||||
// CHECK-NEXT: QualName: 'void'
|
||||
// CHECK-NEXT:...
|
||||
@@ -1,148 +0,0 @@
|
||||
// RUN: rm -rf %t && mkdir -p %t
|
||||
// RUN: clang-doc --doxygen --executor=standalone %S/../Inputs/templates.cpp -output=%t/docs
|
||||
// RUN: cat %t/docs/index.yaml | FileCheck %s --check-prefix=YAML
|
||||
|
||||
// YAML: ---
|
||||
// YAML-NEXT: USR: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: ChildRecords:
|
||||
// YAML-NEXT: - Type: Record
|
||||
// YAML-NEXT: Name: 'tuple'
|
||||
// YAML-NEXT: QualName: 'tuple'
|
||||
// YAML-NEXT: USR: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: Path: 'GlobalNamespace'
|
||||
// YAML-NEXT: ChildFunctions:
|
||||
// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: Name: 'ParamPackFunction'
|
||||
// YAML-NEXT: Location:
|
||||
// YAML-NEXT: - LineNumber: 1
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: Params:
|
||||
// YAML-NEXT: - Type:
|
||||
// YAML-NEXT: Name: 'T...'
|
||||
// YAML-NEXT: QualName: 'T...'
|
||||
// YAML-NEXT: Name: 'args'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'void'
|
||||
// YAML-NEXT: QualName: 'void'
|
||||
// YAML-NEXT: Template:
|
||||
// YAML-NEXT: Params:
|
||||
// YAML-NEXT: - Contents: 'class... T'
|
||||
|
||||
// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: Name: 'function'
|
||||
// YAML-NEXT: DefLocation:
|
||||
// YAML-NEXT: LineNumber: 3
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: Params:
|
||||
// YAML-NEXT: - Type:
|
||||
// YAML-NEXT: Name: 'T'
|
||||
// YAML-NEXT: QualName: 'T'
|
||||
// YAML-NEXT: Name: 'x'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'void'
|
||||
// YAML-NEXT: QualName: 'void'
|
||||
// YAML-NEXT: Template:
|
||||
// YAML-NEXT: Params:
|
||||
// YAML-NEXT: - Contents: 'typename T'
|
||||
// YAML-NEXT: - Contents: 'int U = 1'
|
||||
|
||||
// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: Name: 'longFunction'
|
||||
// YAML-NEXT: DefLocation:
|
||||
// YAML-NEXT: LineNumber: 6
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: Params:
|
||||
// YAML-NEXT: - Type:
|
||||
// YAML-NEXT: Name: 'A'
|
||||
// YAML-NEXT: QualName: 'A'
|
||||
// YAML-NEXT: Name: 'a'
|
||||
// YAML-NEXT: - Type:
|
||||
// YAML-NEXT: Name: 'B'
|
||||
// YAML-NEXT: QualName: 'B'
|
||||
// YAML-NEXT: Name: 'b'
|
||||
// YAML-NEXT: - Type:
|
||||
// YAML-NEXT: Name: 'C'
|
||||
// YAML-NEXT: QualName: 'C'
|
||||
// YAML-NEXT: Name: 'c'
|
||||
// YAML-NEXT: - Type:
|
||||
// YAML-NEXT: Name: 'D'
|
||||
// YAML-NEXT: QualName: 'D'
|
||||
// YAML-NEXT: Name: 'd'
|
||||
// YAML-NEXT: - Type:
|
||||
// YAML-NEXT: Name: 'E'
|
||||
// YAML-NEXT: QualName: 'E'
|
||||
// YAML-NEXT: Name: 'e'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'void'
|
||||
// YAML-NEXT: QualName: 'void'
|
||||
// YAML-NEXT: Template:
|
||||
// YAML-NEXT: Params:
|
||||
// YAML-NEXT: - Contents: 'typename A'
|
||||
// YAML-NEXT: - Contents: 'typename B'
|
||||
// YAML-NEXT: - Contents: 'typename C'
|
||||
// YAML-NEXT: - Contents: 'typename D'
|
||||
// YAML-NEXT: - Contents: 'typename E'
|
||||
|
||||
// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: Name: 'function'
|
||||
// YAML-NEXT: DefLocation:
|
||||
// YAML-NEXT: LineNumber: 8
|
||||
// YAML-NEXT: Filename: '{{.*}}'
|
||||
// YAML-NEXT: Params:
|
||||
// YAML-NEXT: - Type:
|
||||
// YAML-NEXT: Name: 'bool'
|
||||
// YAML-NEXT: QualName: 'bool'
|
||||
// YAML-NEXT: Name: 'x'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Name: 'void'
|
||||
// YAML-NEXT: QualName: 'void'
|
||||
// YAML-NEXT: Template:
|
||||
// YAML-NEXT: Specialization:
|
||||
// YAML-NEXT: SpecializationOf: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: Params:
|
||||
// YAML-NEXT: - Contents: 'bool'
|
||||
// YAML-NEXT: - Contents: '0'
|
||||
|
||||
// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: Name: 'func_with_tuple_param'
|
||||
// YAML-NEXT: Description:
|
||||
// YAML-NEXT: - Kind: FullComment
|
||||
// YAML-NEXT: Children:
|
||||
// YAML-NEXT: - Kind: ParagraphComment
|
||||
// YAML-NEXT: Children:
|
||||
// YAML-NEXT: - Kind: TextComment
|
||||
// YAML-NEXT: Text: 'A function with a tuple parameter'
|
||||
// YAML-NEXT: - Kind: ParagraphComment
|
||||
// YAML-NEXT: Children:
|
||||
// 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: Children:
|
||||
// YAML-NEXT: - Kind: TextComment
|
||||
// YAML-NEXT: Text: 'The input to func_with_tuple_param'
|
||||
// YAML-NEXT: DefLocation:
|
||||
// YAML-NEXT: LineNumber: 18
|
||||
// YAML-NEXT: Filename:
|
||||
// YAML-NEXT: Params:
|
||||
// YAML-NEXT: - Type:
|
||||
// YAML-NEXT: Type: Record
|
||||
// YAML-NEXT: Name: 'tuple'
|
||||
// YAML-NEXT: QualName: 'tuple<int, int, bool>'
|
||||
// YAML-NEXT: USR: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: Path: 'GlobalNamespace'
|
||||
// YAML-NEXT: Name: 't'
|
||||
// YAML-NEXT: ReturnType:
|
||||
// YAML-NEXT: Type:
|
||||
// YAML-NEXT: Type: Record
|
||||
// YAML-NEXT: Name: 'tuple'
|
||||
// YAML-NEXT: QualName: 'tuple<int, int, bool>'
|
||||
// YAML-NEXT: USR: '{{([0-9A-F]{40})}}'
|
||||
// YAML-NEXT: Path: 'GlobalNamespace'
|
||||
// YAML-NEXT: ...
|
||||
@@ -28,7 +28,6 @@ add_extra_unittest(ClangDocTests
|
||||
HTMLGeneratorTest.cpp
|
||||
MergeTest.cpp
|
||||
SerializeTest.cpp
|
||||
YAMLGeneratorTest.cpp
|
||||
JSONGeneratorTest.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -1,593 +0,0 @@
|
||||
//===-- clang-doc/YAMLGeneratorTest.cpp
|
||||
//------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "ClangDocTest.h"
|
||||
#include "Generators.h"
|
||||
#include "Representation.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace clang {
|
||||
namespace doc {
|
||||
|
||||
static std::unique_ptr<Generator> getYAMLGenerator() {
|
||||
auto G = doc::findGeneratorByName("yaml");
|
||||
if (!G)
|
||||
return nullptr;
|
||||
return std::move(G.get());
|
||||
}
|
||||
|
||||
class YAMLGeneratorTest : public ClangDocContextTest {};
|
||||
|
||||
TEST_F(YAMLGeneratorTest, emitNamespaceYAML) {
|
||||
NamespaceInfo I;
|
||||
I.Name = "Namespace";
|
||||
I.Path = "path/to/A";
|
||||
Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
|
||||
I.Namespace = llvm::ArrayRef(Ns);
|
||||
|
||||
Reference NewNamespace(EmptySID, "ChildNamespace", InfoType::IT_namespace,
|
||||
"path::to::A::Namespace::ChildNamespace",
|
||||
"path/to/A/Namespace");
|
||||
InfoNode<Reference> NewNamespaceNode(&NewNamespace);
|
||||
I.Children.Namespaces.push_back(NewNamespaceNode);
|
||||
|
||||
Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record,
|
||||
"path::to::A::Namespace::ChildStruct",
|
||||
"path/to/A/Namespace");
|
||||
InfoNode<Reference> ChildStructNode(&ChildStruct);
|
||||
I.Children.Records.push_back(ChildStructNode);
|
||||
|
||||
FunctionInfo F;
|
||||
F.Name = "OneFunction";
|
||||
F.Access = AccessSpecifier::AS_none;
|
||||
InfoNode<FunctionInfo> FNode(&F);
|
||||
I.Children.Functions.push_back(FNode);
|
||||
|
||||
EnumInfo E;
|
||||
E.Name = "OneEnum";
|
||||
InfoNode<EnumInfo> ENode(&E);
|
||||
I.Children.Enums.push_back(ENode);
|
||||
|
||||
auto G = getYAMLGenerator();
|
||||
assert(G);
|
||||
std::string Buffer;
|
||||
llvm::raw_string_ostream Actual(Buffer);
|
||||
auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext());
|
||||
assert(!Err);
|
||||
std::string Expected =
|
||||
R"raw(---
|
||||
USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'Namespace'
|
||||
Path: 'path/to/A'
|
||||
Namespace:
|
||||
- Type: Namespace
|
||||
Name: 'A'
|
||||
QualName: 'A'
|
||||
ChildNamespaces:
|
||||
- Type: Namespace
|
||||
Name: 'ChildNamespace'
|
||||
QualName: 'path::to::A::Namespace::ChildNamespace'
|
||||
Path: 'path/to/A/Namespace'
|
||||
ChildRecords:
|
||||
- Type: Record
|
||||
Name: 'ChildStruct'
|
||||
QualName: 'path::to::A::Namespace::ChildStruct'
|
||||
Path: 'path/to/A/Namespace'
|
||||
ChildFunctions:
|
||||
- USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'OneFunction'
|
||||
ReturnType: {}
|
||||
ChildEnums:
|
||||
- USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'OneEnum'
|
||||
...
|
||||
)raw";
|
||||
EXPECT_EQ(Expected, Actual.str());
|
||||
}
|
||||
|
||||
TEST_F(YAMLGeneratorTest, emitRecordYAML) {
|
||||
RecordInfo I;
|
||||
I.Name = "r";
|
||||
I.Path = "path/to/A";
|
||||
I.IsTypeDef = true;
|
||||
Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
|
||||
I.Namespace = llvm::ArrayRef(Ns);
|
||||
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
Location Loc1(12, 12, "test.cpp");
|
||||
InfoNode<Location> Loc1Node(&Loc1);
|
||||
I.Loc.push_back(Loc1Node);
|
||||
|
||||
MemberTypeInfo M(TypeInfo("int"), "X", AccessSpecifier::AS_private);
|
||||
|
||||
// Member documentation.
|
||||
CommentInfo BriefChildren[] = {CommentInfo(CommentKind::CK_TextComment, {},
|
||||
"Value of the thing.",
|
||||
"ParagraphComment")};
|
||||
CommentInfo TopCommentChildren[] = {
|
||||
CommentInfo(CommentKind::CK_ParagraphComment, BriefChildren)};
|
||||
CommentInfo TopComment(CommentKind::CK_FullComment, TopCommentChildren);
|
||||
InfoNode<CommentInfo> TopCommentNode(&TopComment);
|
||||
M.Description.push_back(TopCommentNode);
|
||||
MemberTypeInfo MemArr[] = {std::move(M)};
|
||||
I.Members = llvm::ArrayRef(MemArr);
|
||||
|
||||
I.TagType = TagTypeKind::Class;
|
||||
BaseRecordInfo B(EmptySID, "F", "path/to/F", true, AccessSpecifier::AS_public,
|
||||
true);
|
||||
FunctionInfo F;
|
||||
F.Name = "InheritedFunctionOne";
|
||||
InfoNode<FunctionInfo> FNode(&F);
|
||||
B.Children.Functions.push_back(FNode);
|
||||
MemberTypeInfo BMem[] = {
|
||||
MemberTypeInfo(TypeInfo("int"), "N", AccessSpecifier::AS_private)};
|
||||
B.Members = llvm::ArrayRef(BMem);
|
||||
BaseRecordInfo Bases[] = {std::move(B)};
|
||||
I.Bases = llvm::ArrayRef(Bases);
|
||||
|
||||
// F is in the global namespace
|
||||
Reference Parents[] = {Reference(EmptySID, "F", InfoType::IT_record, "")};
|
||||
I.Parents = llvm::ArrayRef(Parents);
|
||||
Reference VParents[] = {Reference(EmptySID, "G", InfoType::IT_record,
|
||||
"path::to::G::G", "path/to/G")};
|
||||
I.VirtualParents = llvm::ArrayRef(VParents);
|
||||
|
||||
Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record,
|
||||
"path::to::A::r::ChildStruct", "path/to/A/r");
|
||||
InfoNode<Reference> ChildStructNode(&ChildStruct);
|
||||
I.Children.Records.push_back(ChildStructNode);
|
||||
|
||||
FunctionInfo F2;
|
||||
F2.Name = "OneFunction";
|
||||
InfoNode<FunctionInfo> F2Node(&F2);
|
||||
I.Children.Functions.push_back(F2Node);
|
||||
|
||||
EnumInfo E;
|
||||
E.Name = "OneEnum";
|
||||
InfoNode<EnumInfo> ENode(&E);
|
||||
I.Children.Enums.push_back(ENode);
|
||||
|
||||
auto G = getYAMLGenerator();
|
||||
assert(G);
|
||||
std::string Buffer;
|
||||
llvm::raw_string_ostream Actual(Buffer);
|
||||
auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext());
|
||||
assert(!Err);
|
||||
std::string Expected =
|
||||
R"raw(---
|
||||
USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'r'
|
||||
Path: 'path/to/A'
|
||||
Namespace:
|
||||
- Type: Namespace
|
||||
Name: 'A'
|
||||
QualName: 'A'
|
||||
DefLocation:
|
||||
LineNumber: 10
|
||||
Filename: 'test.cpp'
|
||||
Location:
|
||||
- LineNumber: 12
|
||||
Filename: 'test.cpp'
|
||||
TagType: Class
|
||||
IsTypeDef: true
|
||||
Members:
|
||||
- Type:
|
||||
Name: 'int'
|
||||
QualName: 'int'
|
||||
Name: 'X'
|
||||
Access: Private
|
||||
Description:
|
||||
- Kind: FullComment
|
||||
Children:
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: TextComment
|
||||
Text: 'Value of the thing.'
|
||||
Name: 'ParagraphComment'
|
||||
Bases:
|
||||
- USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'F'
|
||||
Path: 'path/to/F'
|
||||
TagType: Struct
|
||||
Members:
|
||||
- Type:
|
||||
Name: 'int'
|
||||
QualName: 'int'
|
||||
Name: 'N'
|
||||
Access: Private
|
||||
ChildFunctions:
|
||||
- USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'InheritedFunctionOne'
|
||||
ReturnType: {}
|
||||
Access: Public
|
||||
IsVirtual: true
|
||||
Access: Public
|
||||
IsParent: true
|
||||
Parents:
|
||||
- Type: Record
|
||||
Name: 'F'
|
||||
VirtualParents:
|
||||
- Type: Record
|
||||
Name: 'G'
|
||||
QualName: 'path::to::G::G'
|
||||
Path: 'path/to/G'
|
||||
ChildRecords:
|
||||
- Type: Record
|
||||
Name: 'ChildStruct'
|
||||
QualName: 'path::to::A::r::ChildStruct'
|
||||
Path: 'path/to/A/r'
|
||||
ChildFunctions:
|
||||
- USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'OneFunction'
|
||||
ReturnType: {}
|
||||
Access: Public
|
||||
ChildEnums:
|
||||
- USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'OneEnum'
|
||||
...
|
||||
)raw";
|
||||
EXPECT_EQ(Expected, Actual.str());
|
||||
}
|
||||
|
||||
TEST_F(YAMLGeneratorTest, emitFunctionYAML) {
|
||||
FunctionInfo I;
|
||||
I.Name = "f";
|
||||
Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
|
||||
I.Namespace = llvm::ArrayRef(Ns);
|
||||
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
Location Loc1(12, 12, "test.cpp");
|
||||
InfoNode<Location> Loc1Node(&Loc1);
|
||||
I.Loc.push_back(Loc1Node);
|
||||
|
||||
I.Access = AccessSpecifier::AS_none;
|
||||
|
||||
I.ReturnType = TypeInfo(Reference(EmptySID, "void", InfoType::IT_default));
|
||||
|
||||
FieldTypeInfo P1(TypeInfo("int"), "P");
|
||||
FieldTypeInfo D(TypeInfo("double"), "D");
|
||||
D.DefaultValue = "2.0 * M_PI";
|
||||
FieldTypeInfo Params[] = {std::move(P1), std::move(D)};
|
||||
I.Params = llvm::ArrayRef(Params);
|
||||
I.IsMethod = true;
|
||||
I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
|
||||
|
||||
auto G = getYAMLGenerator();
|
||||
assert(G);
|
||||
std::string Buffer;
|
||||
llvm::raw_string_ostream Actual(Buffer);
|
||||
auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext());
|
||||
assert(!Err);
|
||||
std::string Expected =
|
||||
R"raw(---
|
||||
USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'f'
|
||||
Namespace:
|
||||
- Type: Namespace
|
||||
Name: 'A'
|
||||
QualName: 'A'
|
||||
DefLocation:
|
||||
LineNumber: 10
|
||||
Filename: 'test.cpp'
|
||||
Location:
|
||||
- LineNumber: 12
|
||||
Filename: 'test.cpp'
|
||||
IsMethod: true
|
||||
Parent:
|
||||
Type: Record
|
||||
Name: 'Parent'
|
||||
QualName: 'Parent'
|
||||
Params:
|
||||
- Type:
|
||||
Name: 'int'
|
||||
QualName: 'int'
|
||||
Name: 'P'
|
||||
- Type:
|
||||
Name: 'double'
|
||||
QualName: 'double'
|
||||
Name: 'D'
|
||||
DefaultValue: '2.0 * M_PI'
|
||||
ReturnType:
|
||||
Type:
|
||||
Name: 'void'
|
||||
QualName: 'void'
|
||||
...
|
||||
)raw";
|
||||
EXPECT_EQ(Expected, Actual.str());
|
||||
}
|
||||
|
||||
// Tests the equivalent of:
|
||||
// namespace A {
|
||||
// enum e { X };
|
||||
// }
|
||||
TEST_F(YAMLGeneratorTest, emitSimpleEnumYAML) {
|
||||
EnumInfo I;
|
||||
I.Name = "e";
|
||||
Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)};
|
||||
I.Namespace = llvm::ArrayRef(Ns);
|
||||
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
Location Loc1(12, 12, "test.cpp");
|
||||
InfoNode<Location> Loc1Node(&Loc1);
|
||||
I.Loc.push_back(Loc1Node);
|
||||
|
||||
EnumValueInfo EV[] = {EnumValueInfo("X")};
|
||||
I.Members = llvm::ArrayRef(EV);
|
||||
I.Scoped = false;
|
||||
|
||||
auto G = getYAMLGenerator();
|
||||
assert(G);
|
||||
std::string Buffer;
|
||||
llvm::raw_string_ostream Actual(Buffer);
|
||||
auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext());
|
||||
assert(!Err);
|
||||
std::string Expected =
|
||||
R"raw(---
|
||||
USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'e'
|
||||
Namespace:
|
||||
- Type: Namespace
|
||||
Name: 'A'
|
||||
QualName: 'A'
|
||||
DefLocation:
|
||||
LineNumber: 10
|
||||
Filename: 'test.cpp'
|
||||
Location:
|
||||
- LineNumber: 12
|
||||
Filename: 'test.cpp'
|
||||
Members:
|
||||
- Name: 'X'
|
||||
Value: '0'
|
||||
...
|
||||
)raw";
|
||||
EXPECT_EQ(Expected, Actual.str());
|
||||
}
|
||||
|
||||
// Tests the equivalent of:
|
||||
// enum class e : short { X = FOO_BAR + 2 };
|
||||
TEST_F(YAMLGeneratorTest, enumTypedScopedEnumYAML) {
|
||||
EnumInfo I;
|
||||
I.Name = "e";
|
||||
|
||||
EnumValueInfo EV[] = {EnumValueInfo("X", "-9876", "FOO_BAR + 2")};
|
||||
I.Members = llvm::ArrayRef(EV);
|
||||
I.Scoped = true;
|
||||
I.BaseType = TypeInfo("short");
|
||||
|
||||
auto G = getYAMLGenerator();
|
||||
assert(G);
|
||||
std::string Buffer;
|
||||
llvm::raw_string_ostream Actual(Buffer);
|
||||
auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext());
|
||||
assert(!Err);
|
||||
std::string Expected =
|
||||
R"raw(---
|
||||
USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'e'
|
||||
Scoped: true
|
||||
BaseType:
|
||||
Type:
|
||||
Name: 'short'
|
||||
QualName: 'short'
|
||||
Members:
|
||||
- Name: 'X'
|
||||
Value: '-9876'
|
||||
Expr: 'FOO_BAR + 2'
|
||||
...
|
||||
)raw";
|
||||
EXPECT_EQ(Expected, Actual.str());
|
||||
}
|
||||
|
||||
TEST_F(YAMLGeneratorTest, enumTypedefYAML) {
|
||||
TypedefInfo I;
|
||||
I.Name = "MyUsing";
|
||||
I.Underlying = TypeInfo("int");
|
||||
I.IsUsing = true;
|
||||
|
||||
auto G = getYAMLGenerator();
|
||||
assert(G);
|
||||
std::string Buffer;
|
||||
llvm::raw_string_ostream Actual(Buffer);
|
||||
auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext());
|
||||
assert(!Err);
|
||||
std::string Expected =
|
||||
R"raw(---
|
||||
USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'MyUsing'
|
||||
Underlying:
|
||||
Name: 'int'
|
||||
QualName: 'int'
|
||||
IsUsing: true
|
||||
...
|
||||
)raw";
|
||||
EXPECT_EQ(Expected, Actual.str());
|
||||
}
|
||||
|
||||
TEST_F(YAMLGeneratorTest, emitCommentYAML) {
|
||||
FunctionInfo I;
|
||||
I.Name = "f";
|
||||
I.DefLoc = Location(10, 10, "test.cpp");
|
||||
I.ReturnType = TypeInfo("void");
|
||||
FieldTypeInfo Params[] = {FieldTypeInfo(TypeInfo("int"), "I"),
|
||||
FieldTypeInfo(TypeInfo("int"), "J")};
|
||||
I.Params = llvm::ArrayRef(Params);
|
||||
I.Access = AccessSpecifier::AS_none;
|
||||
|
||||
// BlankLine
|
||||
CommentInfo BlankChildren[] = {CommentInfo(CommentKind::CK_TextComment)};
|
||||
CommentInfo BlankLine(CommentKind::CK_ParagraphComment, BlankChildren);
|
||||
|
||||
// Brief
|
||||
CommentInfo BriefChildren[] = {CommentInfo(CommentKind::CK_TextComment, {},
|
||||
" Brief description.",
|
||||
"ParagraphComment")};
|
||||
CommentInfo Brief(CommentKind::CK_ParagraphComment, BriefChildren);
|
||||
|
||||
// Extended
|
||||
CommentInfo ExtChildren[] = {CommentInfo(CommentKind::CK_TextComment, {},
|
||||
" Extended description that"),
|
||||
CommentInfo(CommentKind::CK_TextComment, {},
|
||||
" continues onto the next line.")};
|
||||
CommentInfo Extended(CommentKind::CK_ParagraphComment, ExtChildren);
|
||||
|
||||
// HTML
|
||||
StringRef HtmlKeys[] = {"class"};
|
||||
StringRef HtmlValues[] = {"test"};
|
||||
CommentInfo HtmlStart(CommentKind::CK_HTMLStartTagComment, {}, "", "ul", "",
|
||||
"", "", false, false, HtmlKeys, HtmlValues);
|
||||
CommentInfo HtmlStartLi(CommentKind::CK_HTMLStartTagComment, {}, "", "li");
|
||||
CommentInfo HtmlEnd(CommentKind::CK_HTMLEndTagComment, {}, "", "ul", "", "",
|
||||
"", false, true);
|
||||
|
||||
CommentInfo HtmlChildren[] = {
|
||||
CommentInfo(CommentKind::CK_TextComment), HtmlStart, HtmlStartLi,
|
||||
CommentInfo(CommentKind::CK_TextComment, {}, " Testing."), HtmlEnd};
|
||||
CommentInfo HTML(CommentKind::CK_ParagraphComment, HtmlChildren);
|
||||
|
||||
// Verbatim
|
||||
CommentInfo VerbLine(CommentKind::CK_VerbatimBlockLineComment, {},
|
||||
" The description continues.");
|
||||
CommentInfo VerbChildren[] = {VerbLine};
|
||||
CommentInfo Verbatim(CommentKind::CK_VerbatimBlockComment, VerbChildren, "",
|
||||
"verbatim", "endverbatim");
|
||||
|
||||
// ParamOut
|
||||
CommentInfo ParamOutParaChildren[] = {
|
||||
CommentInfo(CommentKind::CK_TextComment),
|
||||
CommentInfo(CommentKind::CK_TextComment, {}, " is a parameter.")};
|
||||
CommentInfo ParamOutPara(CommentKind::CK_ParagraphComment,
|
||||
ParamOutParaChildren);
|
||||
CommentInfo ParamOutChildren[] = {ParamOutPara};
|
||||
CommentInfo ParamOut(CommentKind::CK_ParamCommandComment, ParamOutChildren,
|
||||
"", "", "", "[out]", "I", true);
|
||||
|
||||
// ParamIn
|
||||
CommentInfo ParamInParaChildren[] = {
|
||||
CommentInfo(CommentKind::CK_TextComment, {}, " is a parameter."),
|
||||
CommentInfo(CommentKind::CK_TextComment)};
|
||||
CommentInfo ParamInPara(CommentKind::CK_ParagraphComment,
|
||||
ParamInParaChildren);
|
||||
CommentInfo ParamInChildren[] = {ParamInPara};
|
||||
CommentInfo ParamIn(CommentKind::CK_ParamCommandComment, ParamInChildren, "",
|
||||
"", "", "[in]", "J");
|
||||
|
||||
// Return
|
||||
CommentInfo ReturnParaChildren[] = {
|
||||
CommentInfo(CommentKind::CK_TextComment, {}, "void")};
|
||||
CommentInfo ReturnPara(CommentKind::CK_ParagraphComment, ReturnParaChildren);
|
||||
CommentInfo ReturnChildren[] = {ReturnPara};
|
||||
CommentInfo Return(CommentKind::CK_BlockCommandComment, ReturnChildren, "",
|
||||
"return", "", "", "", true);
|
||||
|
||||
CommentInfo TopChildren[] = {BlankLine, Brief, Extended, HTML,
|
||||
Verbatim, ParamOut, ParamIn, Return};
|
||||
CommentInfo Top(CommentKind::CK_FullComment, TopChildren);
|
||||
InfoNode<CommentInfo> TopNode(&Top);
|
||||
I.Description.push_back(TopNode);
|
||||
|
||||
auto G = getYAMLGenerator();
|
||||
assert(G);
|
||||
std::string Buffer;
|
||||
llvm::raw_string_ostream Actual(Buffer);
|
||||
auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext());
|
||||
assert(!Err);
|
||||
std::string Expected =
|
||||
R"raw(---
|
||||
USR: '0000000000000000000000000000000000000000'
|
||||
Name: 'f'
|
||||
Description:
|
||||
- Kind: FullComment
|
||||
Children:
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: TextComment
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: TextComment
|
||||
Text: ' Brief description.'
|
||||
Name: 'ParagraphComment'
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: TextComment
|
||||
Text: ' Extended description that'
|
||||
- Kind: TextComment
|
||||
Text: ' continues onto the next line.'
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: TextComment
|
||||
- Kind: HTMLStartTagComment
|
||||
Name: 'ul'
|
||||
AttrKeys:
|
||||
- 'class'
|
||||
AttrValues:
|
||||
- 'test'
|
||||
- Kind: HTMLStartTagComment
|
||||
Name: 'li'
|
||||
- Kind: TextComment
|
||||
Text: ' Testing.'
|
||||
- Kind: HTMLEndTagComment
|
||||
Name: 'ul'
|
||||
SelfClosing: true
|
||||
- Kind: VerbatimBlockComment
|
||||
Name: 'verbatim'
|
||||
CloseName: 'endverbatim'
|
||||
Children:
|
||||
- Kind: VerbatimBlockLineComment
|
||||
Text: ' The description continues.'
|
||||
- Kind: ParamCommandComment
|
||||
Direction: '[out]'
|
||||
ParamName: 'I'
|
||||
Explicit: true
|
||||
Children:
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: TextComment
|
||||
- Kind: TextComment
|
||||
Text: ' is a parameter.'
|
||||
- Kind: ParamCommandComment
|
||||
Direction: '[in]'
|
||||
ParamName: 'J'
|
||||
Children:
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: TextComment
|
||||
Text: ' is a parameter.'
|
||||
- Kind: TextComment
|
||||
- Kind: BlockCommandComment
|
||||
Name: 'return'
|
||||
Explicit: true
|
||||
Children:
|
||||
- Kind: ParagraphComment
|
||||
Children:
|
||||
- Kind: TextComment
|
||||
Text: 'void'
|
||||
DefLocation:
|
||||
LineNumber: 10
|
||||
Filename: 'test.cpp'
|
||||
Params:
|
||||
- Type:
|
||||
Name: 'int'
|
||||
QualName: 'int'
|
||||
Name: 'I'
|
||||
- Type:
|
||||
Name: 'int'
|
||||
QualName: 'int'
|
||||
Name: 'J'
|
||||
ReturnType:
|
||||
Type:
|
||||
Name: 'void'
|
||||
QualName: 'void'
|
||||
...
|
||||
)raw";
|
||||
|
||||
EXPECT_EQ(Expected, Actual.str());
|
||||
}
|
||||
|
||||
} // namespace doc
|
||||
} // namespace clang
|
||||
Reference in new issue
Block a user