Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 76 additions & 46 deletions clang-tools-extra/clang-doc/JSONGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ using namespace llvm::json;
namespace clang {
namespace doc {

// FIXME: These static methods should be refactored into methods for
// `JSONGenerator`. It's cumbersome to pass around important properties from
// ClangDocContext using these static methods.
class JSONGenerator : public Generator {
public:
static const char *Format;
Expand All @@ -25,7 +28,8 @@ const char *JSONGenerator::Format = "json";

static void serializeInfo(const ConstraintInfo &I, Object &Obj);
static void serializeInfo(const RecordInfo &I, Object &Obj,
const std::optional<StringRef> &RepositoryUrl);
const std::optional<StringRef> &RepositoryUrl,
const std::optional<StringRef> &RepositoryLinePrefix);

static void serializeReference(const Reference &Ref, Object &ReferenceObj);

Expand Down Expand Up @@ -75,7 +79,8 @@ static std::string infoTypeToString(InfoType IT) {

static json::Object
serializeLocation(const Location &Loc,
const std::optional<StringRef> RepositoryUrl) {
const std::optional<StringRef> RepositoryUrl,
const std::optional<StringRef> RepositoryLinePrefix) {
Object LocationObj = Object();
LocationObj["LineNumber"] = Loc.StartLineNumber;
LocationObj["Filename"] = Loc.Filename;
Expand All @@ -84,7 +89,14 @@ serializeLocation(const Location &Loc,
return LocationObj;
SmallString<128> FileURL(*RepositoryUrl);
sys::path::append(FileURL, sys::path::Style::posix, Loc.Filename);
FileURL += "#" + std::to_string(Loc.StartLineNumber);

std::string LinePrefix;
if (!RepositoryLinePrefix)
LinePrefix = "#L";
else
LinePrefix = *RepositoryLinePrefix;

FileURL += LinePrefix + std::to_string(Loc.StartLineNumber);
LocationObj["FileURL"] = FileURL;
return LocationObj;
}
Expand Down Expand Up @@ -338,7 +350,8 @@ static void generateContext(const Info &I, Object &Obj) {

static void
serializeCommonAttributes(const Info &I, json::Object &Obj,
const std::optional<StringRef> RepositoryUrl) {
const std::optional<StringRef> RepositoryUrl,
const std::optional<StringRef> RepositoryLinePrefix) {
insertNonEmpty("Name", I.Name, Obj);
Obj["USR"] = toHex(toStringRef(I.USR));
Obj["InfoType"] = infoTypeToString(I.IT);
Expand Down Expand Up @@ -378,8 +391,8 @@ serializeCommonAttributes(const Info &I, json::Object &Obj,
if (I.IT != InfoType::IT_namespace) {
const auto *Symbol = static_cast<const SymbolInfo *>(&I);
if (Symbol->DefLoc)
Obj["Location"] =
serializeLocation(Symbol->DefLoc.value(), RepositoryUrl);
Obj["Location"] = serializeLocation(Symbol->DefLoc.value(), RepositoryUrl,
RepositoryLinePrefix);
}

if (!I.Contexts.empty())
Expand All @@ -405,11 +418,12 @@ static void serializeReference(const Reference &Ref, Object &ReferenceObj) {
// differently. Only enums, records, and typedefs are handled here.
static void
serializeCommonChildren(const ScopeChildren &Children, json::Object &Obj,
const std::optional<StringRef> RepositoryUrl) {
static auto SerializeInfo = [RepositoryUrl](const auto &Info,
Object &Object) {
serializeInfo(Info, Object, RepositoryUrl);
};
const std::optional<StringRef> RepositoryUrl,
const std::optional<StringRef> RepositoryLinePrefix) {
static auto SerializeInfo =
[RepositoryUrl, RepositoryLinePrefix](const auto &Info, Object &Object) {
serializeInfo(Info, Object, RepositoryUrl, RepositoryLinePrefix);
};

if (!Children.Enums.empty()) {
serializeArray(Children.Enums, Obj, "Enums", SerializeInfo);
Expand Down Expand Up @@ -492,8 +506,9 @@ static void serializeInfo(const TemplateInfo &Template, Object &Obj) {
}

static void serializeInfo(const ConceptInfo &I, Object &Obj,
const std::optional<StringRef> &RepositoryUrl) {
serializeCommonAttributes(I, Obj, RepositoryUrl);
const std::optional<StringRef> &RepositoryUrl,
const std::optional<StringRef> &RepositoryLine) {
serializeCommonAttributes(I, Obj, RepositoryUrl, RepositoryLine);
Obj["IsType"] = I.IsType;
Obj["ConstraintExpression"] = I.ConstraintExpression;
serializeInfo(I.Template, Obj);
Expand All @@ -517,8 +532,9 @@ static void serializeInfo(const FieldTypeInfo &I, Object &Obj) {
}

static void serializeInfo(const FunctionInfo &F, json::Object &Obj,
const std::optional<StringRef> RepositoryURL) {
serializeCommonAttributes(F, Obj, RepositoryURL);
const std::optional<StringRef> RepositoryURL,
const std::optional<StringRef> RepositoryLine) {
serializeCommonAttributes(F, Obj, RepositoryURL, RepositoryLine);
Obj["IsStatic"] = F.IsStatic;

auto ReturnTypeObj = Object();
Expand All @@ -541,8 +557,9 @@ static void serializeInfo(const EnumValueInfo &I, Object &Obj) {
}

static void serializeInfo(const EnumInfo &I, json::Object &Obj,
const std::optional<StringRef> &RepositoryUrl) {
serializeCommonAttributes(I, Obj, RepositoryUrl);
const std::optional<StringRef> &RepositoryUrl,
const std::optional<StringRef> &RepositoryLine) {
serializeCommonAttributes(I, Obj, RepositoryUrl, RepositoryLine);
Obj["Scoped"] = I.Scoped;

if (I.BaseType) {
Expand All @@ -558,9 +575,11 @@ static void serializeInfo(const EnumInfo &I, json::Object &Obj,
serializeArray(I.Members, Obj, "Members", SerializeInfoLambda);
}

static void serializeInfo(const TypedefInfo &I, json::Object &Obj,
const std::optional<StringRef> &RepositoryUrl) {
serializeCommonAttributes(I, Obj, RepositoryUrl);
static void
serializeInfo(const TypedefInfo &I, json::Object &Obj,
const std::optional<StringRef> &RepositoryUrl,
const std::optional<StringRef> &RepositoryLinePrefix) {
serializeCommonAttributes(I, Obj, RepositoryUrl, RepositoryLinePrefix);
Obj["TypeDeclaration"] = I.TypeDeclaration;
Obj["IsUsing"] = I.IsUsing;
json::Value TypeVal = Object();
Expand All @@ -571,9 +590,12 @@ static void serializeInfo(const TypedefInfo &I, json::Object &Obj,
serializeInfo(I.Template.value(), Obj);
}

static void serializeInfo(const BaseRecordInfo &I, Object &Obj,
const std::optional<StringRef> &RepositoryUrl) {
serializeInfo(static_cast<const RecordInfo &>(I), Obj, RepositoryUrl);
static void
serializeInfo(const BaseRecordInfo &I, Object &Obj,
const std::optional<StringRef> &RepositoryUrl,
const std::optional<StringRef> &RepositoryLinePrefix) {
serializeInfo(static_cast<const RecordInfo &>(I), Obj, RepositoryUrl,
RepositoryLinePrefix);
Obj["IsVirtual"] = I.IsVirtual;
Obj["Access"] = getAccessSpelling(I.Access);
Obj["IsParent"] = I.IsParent;
Expand All @@ -593,17 +615,19 @@ static void serializeInfo(const FriendInfo &I, Object &Obj) {
serializeInfo(I.ReturnType.value(), ReturnTypeObj);
Obj["ReturnType"] = std::move(ReturnTypeObj);
}
serializeCommonAttributes(I, Obj, std::nullopt);
serializeCommonAttributes(I, Obj, std::nullopt, std::nullopt);
}

static void insertArray(Object &Obj, json::Value &Array, StringRef Key) {
Obj[Key] = Array;
Obj["Has" + Key.str()] = true;
}

static void serializeInfo(const RecordInfo &I, json::Object &Obj,
const std::optional<StringRef> &RepositoryUrl) {
serializeCommonAttributes(I, Obj, RepositoryUrl);
static void
serializeInfo(const RecordInfo &I, json::Object &Obj,
const std::optional<StringRef> &RepositoryUrl,
const std::optional<StringRef> &RepositoryLinePrefix) {
serializeCommonAttributes(I, Obj, RepositoryUrl, RepositoryLinePrefix);
Obj["TagType"] = getTagType(I.TagType);
Obj["IsTypedef"] = I.IsTypeDef;
Obj["MangledName"] = I.MangledName;
Expand All @@ -617,7 +641,7 @@ static void serializeInfo(const RecordInfo &I, json::Object &Obj,
for (const auto &Function : I.Children.Functions) {
json::Value FunctionVal = Object();
auto &FunctionObj = *FunctionVal.getAsObject();
serializeInfo(Function, FunctionObj, RepositoryUrl);
serializeInfo(Function, FunctionObj, RepositoryUrl, RepositoryLinePrefix);
AccessSpecifier Access = Function.Access;
if (Access == AccessSpecifier::AS_public)
PubFunctionsArrayRef.push_back(FunctionVal);
Expand Down Expand Up @@ -663,11 +687,12 @@ static void serializeInfo(const RecordInfo &I, json::Object &Obj,
}

if (!I.Bases.empty())
serializeArray(
I.Bases, Obj, "Bases",
[&RepositoryUrl](const BaseRecordInfo &Base, Object &BaseObj) {
serializeInfo(Base, BaseObj, RepositoryUrl);
});
serializeArray(I.Bases, Obj, "Bases",
[&RepositoryUrl, &RepositoryLinePrefix](
const BaseRecordInfo &Base, Object &BaseObj) {
serializeInfo(Base, BaseObj, RepositoryUrl,
RepositoryLinePrefix);
});

if (!I.Parents.empty()) {
serializeArray(I.Parents, Obj, "Parents", SerializeReferenceLambda);
Expand All @@ -688,21 +713,24 @@ static void serializeInfo(const RecordInfo &I, json::Object &Obj,
Obj["HasFriends"] = true;
}

serializeCommonChildren(I.Children, Obj, RepositoryUrl);
serializeCommonChildren(I.Children, Obj, RepositoryUrl, RepositoryLinePrefix);
}

static void serializeInfo(const VarInfo &I, json::Object &Obj,
const std::optional<StringRef> RepositoryUrl) {
serializeCommonAttributes(I, Obj, RepositoryUrl);
static void
serializeInfo(const VarInfo &I, json::Object &Obj,
const std::optional<StringRef> RepositoryUrl,
const std::optional<StringRef> RepositoryUrlLinePrefix) {
serializeCommonAttributes(I, Obj, RepositoryUrl, RepositoryUrlLinePrefix);
Obj["IsStatic"] = I.IsStatic;
auto TypeObj = Object();
serializeInfo(I.Type, TypeObj);
Obj["Type"] = std::move(TypeObj);
}

static void serializeInfo(const NamespaceInfo &I, json::Object &Obj,
const std::optional<StringRef> RepositoryUrl) {
serializeCommonAttributes(I, Obj, RepositoryUrl);
const std::optional<StringRef> RepositoryUrl,
const std::optional<StringRef> RepositoryLinePrefix) {
serializeCommonAttributes(I, Obj, RepositoryUrl, RepositoryLinePrefix);
if (I.USR == GlobalNamespaceID)
Obj["Name"] = "Global Namespace";

Expand All @@ -712,10 +740,10 @@ static void serializeInfo(const NamespaceInfo &I, json::Object &Obj,
Obj["HasNamespaces"] = true;
}

static auto SerializeInfo = [RepositoryUrl](const auto &Info,
Object &Object) {
serializeInfo(Info, Object, RepositoryUrl);
};
static auto SerializeInfo =
[RepositoryUrl, RepositoryLinePrefix](const auto &Info, Object &Object) {
serializeInfo(Info, Object, RepositoryUrl, RepositoryLinePrefix);
};

if (!I.Children.Functions.empty()) {
serializeArray(I.Children.Functions, Obj, "Functions", SerializeInfo);
Expand All @@ -730,7 +758,7 @@ static void serializeInfo(const NamespaceInfo &I, json::Object &Obj,
if (!I.Children.Variables.empty())
serializeArray(I.Children.Variables, Obj, "Variables", SerializeInfo);

serializeCommonChildren(I.Children, Obj, RepositoryUrl);
serializeCommonChildren(I.Children, Obj, RepositoryUrl, RepositoryLinePrefix);
}

static SmallString<16> determineFileName(Info *I, SmallString<128> &Path) {
Expand Down Expand Up @@ -864,10 +892,12 @@ Error JSONGenerator::generateDocForInfo(Info *I, raw_ostream &OS,

switch (I->IT) {
case InfoType::IT_namespace:
serializeInfo(*static_cast<NamespaceInfo *>(I), Obj, CDCtx.RepositoryUrl);
serializeInfo(*static_cast<NamespaceInfo *>(I), Obj, CDCtx.RepositoryUrl,
CDCtx.RepositoryLinePrefix);
break;
case InfoType::IT_record:
serializeInfo(*static_cast<RecordInfo *>(I), Obj, CDCtx.RepositoryUrl);
serializeInfo(*static_cast<RecordInfo *>(I), Obj, CDCtx.RepositoryUrl,
CDCtx.RepositoryLinePrefix);
break;
case InfoType::IT_concept:
case InfoType::IT_enum:
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clang-doc/assets/alias-template.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
{{>Comments}}
{{/Description}}
{{#Location}}
<p>Defined at line {{LineNumber}} of file {{Filename}}</p>
<p>Defined at line {{LineNumber}} of file {{^FileURL}}{{Filename}}{{/FileURL}}{{#FileURL}}<a href="{{FileURL}}">{{Filename}}</a>{{/FileURL}}</p>
{{/Location}}
</div>
4 changes: 3 additions & 1 deletion clang-tools-extra/clang-doc/assets/class-template.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@
{{/Template}}
<div class="hero__title">
<h1 class="hero__title-large">{{TagType}} {{Name}}</h1>
<p>Defined at line {{Location.LineNumber}} of file {{Location.Filename}}</p>
{{#Location}}
<p>Defined at line {{LineNumber}} of file {{^FileURL}}{{Filename}}{{/FileURL}}{{#FileURL}}<a href="{{FileURL}}">{{Filename}}</a>{{/FileURL}}</p>
{{/Location}}
{{#Description}}
<div class="doc-card">
{{>Comments}}
Expand Down
4 changes: 1 addition & 3 deletions clang-tools-extra/clang-doc/assets/enum-template.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@
</div>
{{/EnumComments}}
{{#Location}}
<div>
Defined at line {{LineNumber}} of file {{Filename}}
</div>
<p>Defined at line {{LineNumber}} of file {{^FileURL}}{{Filename}}{{/FileURL}}{{#FileURL}}<a href="{{FileURL}}">{{Filename}}</a>{{/FileURL}}</p>
{{/Location}}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@
</div>
{{/Description}}
{{#Location}}
<p>Defined at line {{LineNumber}} of file {{Filename}}</p>
<p>Defined at line {{LineNumber}} of file {{^FileURL}}{{Filename}}{{/FileURL}}{{#FileURL}}<a href="{{FileURL}}">{{Filename}}</a>{{/FileURL}}</p>
{{/Location}}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@
{{#Description}}
{{>Comments}}
{{/Description}}
<p>Defined at line {{Location.LineNumber}} of file {{Location.Filename}}</p>
{{#Location}}
<p>Defined at line {{LineNumber}} of file {{^FileURL}}{{Filename}}{{/FileURL}}{{#FileURL}}<a href="{{FileURL}}">{{Filename}}</a>{{/FileURL}}</p>
{{/Location}}
</div>
{{/Concepts}}
</section>
Expand Down
10 changes: 4 additions & 6 deletions clang-tools-extra/test/clang-doc/enum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
*/
enum Color {
// MD-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-INDEX-LINE-NOT: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
// HTML-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
Red, ///< Comment 1
Green, ///< Comment 2
Blue ///< Comment 3
Expand Down Expand Up @@ -64,7 +64,7 @@ enum Color {
*/
enum class Shapes {
// MD-INDEX-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-INDEX-LINE-NOT: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
// HTML-INDEX-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>

/// Comment 1
Circle,
Expand Down Expand Up @@ -115,7 +115,7 @@ class Animals {
*/
enum AnimalType {
// MD-ANIMAL-LINE: *Defined at {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp#[[@LINE-1]]*
// HTML-ANIMAL-LINE-NOT: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
// HTML-ANIMAL-LINE: <p>Defined at line [[@LINE-2]] of file {{.*}}clang-tools-extra{{[\/]}}test{{[\/]}}clang-doc{{[\/]}}enum.cpp</p>
Dog, ///< Man's best friend
Cat, ///< Man's other best friend
Iguana ///< A lizard
Expand Down Expand Up @@ -148,9 +148,7 @@ class Animals {
// HTML-ANIMAL-NEXT: </tr>
// HTML-ANIMAL-NEXT: </tbody>
// HTML-ANIMAL-NEXT: </table>
// HTML-ANIMAL-NEXT: <div>
// HTML-ANIMAL-NEXT: Defined at line 116 of file {{.*}}enum.cpp
// HTML-ANIMAL-NEXT: </div>
// HTML-ANIMAL-NEXT: <p>Defined at line 116 of file {{.*}}enum.cpp</p>
// HTML-ANIMAL-NEXT: </div>
// HTML-ANIMAL-NEXT: </section>

Expand Down
4 changes: 1 addition & 3 deletions clang-tools-extra/test/clang-doc/mustache-index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ class Foo;
// CHECK-NEXT: </tr>
// CHECK-NEXT: </tbody>
// CHECK-NEXT: </table>
// CHECK-NEXT: <div>
// CHECK-NEXT: Defined at line 5 of file {{.*}}mustache-index.cpp
// CHECK-NEXT: </div>
// CHECK-NEXT: <p>Defined at line 5 of file {{.*}}mustache-index.cpp</p>
// CHECK-NEXT: </div>
// CHECK-NEXT: </div>
// CHECK-NEXT: </section>
Expand Down
3 changes: 1 addition & 2 deletions clang-tools-extra/test/clang-doc/templates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,7 @@ void ParamPackFunction(T... args);
// JSON-NEXT: },

// HTML: <pre><code class="language-cpp code-clang-doc">template &lt;class... T&gt;</code></pre>
// HTML-NEXT: <pre><code class="language-cpp code-clang-doc">void ParamPackFunction (T... args)</code></pre>
// HTML-NEXT: </div>
// HTML-NEXT: <pre><code class="language-cpp code-clang-doc">void ParamPackFunction (T... args)</code></pre>

template <typename T, int U = 1>
void function(T x) {}
Expand Down