[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-07-10 Thread Julie Hockett via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL365687: [clang-doc] Add a structured HTML generator 
(authored by juliehockett, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D63857?vs=208792=209040#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857

Files:
  clang-tools-extra/trunk/clang-doc/CMakeLists.txt
  clang-tools-extra/trunk/clang-doc/Generators.cpp
  clang-tools-extra/trunk/clang-doc/Generators.h
  clang-tools-extra/trunk/clang-doc/HTMLGenerator.cpp
  clang-tools-extra/trunk/clang-doc/MDGenerator.cpp
  clang-tools-extra/trunk/clang-doc/tool/ClangDocMain.cpp
  clang-tools-extra/trunk/unittests/clang-doc/CMakeLists.txt
  clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp

Index: clang-tools-extra/trunk/unittests/clang-doc/CMakeLists.txt
===
--- clang-tools-extra/trunk/unittests/clang-doc/CMakeLists.txt
+++ clang-tools-extra/trunk/unittests/clang-doc/CMakeLists.txt
@@ -12,6 +12,7 @@
 add_extra_unittest(ClangDocTests
   BitcodeTest.cpp
   ClangDocTest.cpp
+  HTMLGeneratorTest.cpp
   MDGeneratorTest.cpp
   MergeTest.cpp
   SerializeTest.cpp
Index: clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
===
--- clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
+++ clang-tools-extra/trunk/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -0,0 +1,276 @@
+//===-- clang-doc/HTMLGeneratorTest.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 {
+
+std::unique_ptr getHTMLGenerator() {
+  auto G = doc::findGeneratorByName("html");
+  if (!G)
+return nullptr;
+  return std::move(G.get());
+}
+
+TEST(HTMLGeneratorTest, emitNamespaceHTML) {
+  NamespaceInfo I;
+  I.Name = "Namespace";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.ChildNamespaces.emplace_back(EmptySID, "ChildNamespace",
+ InfoType::IT_namespace);
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+namespace Namespace
+
+  namespace Namespace
+  Namespaces
+  
+ChildNamespace
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitRecordHTML) {
+  RecordInfo I;
+  I.Name = "r";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.Members.emplace_back("int", "X", AccessSpecifier::AS_private);
+  I.TagType = TagTypeKind::TTK_Class;
+  I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
+  I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
+
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+class r
+
+  class r
+  
+Defined at line 10 of test.cpp
+  
+  
+Inherits from F, G
+  
+  Members
+  
+private int X
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitFunctionHTML) {
+  FunctionInfo I;
+  I.Name = "f";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
+  

[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-07-09 Thread Diego Astiazarán via Phabricator via cfe-commits
DiegoAstiazaran updated this revision to Diff 208792.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857

Files:
  clang-tools-extra/clang-doc/CMakeLists.txt
  clang-tools-extra/clang-doc/Generators.cpp
  clang-tools-extra/clang-doc/Generators.h
  clang-tools-extra/clang-doc/HTMLGenerator.cpp
  clang-tools-extra/clang-doc/MDGenerator.cpp
  clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
  clang-tools-extra/unittests/clang-doc/CMakeLists.txt
  clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp

Index: clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
===
--- /dev/null
+++ clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -0,0 +1,276 @@
+//===-- clang-doc/HTMLGeneratorTest.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 {
+
+std::unique_ptr getHTMLGenerator() {
+  auto G = doc::findGeneratorByName("html");
+  if (!G)
+return nullptr;
+  return std::move(G.get());
+}
+
+TEST(HTMLGeneratorTest, emitNamespaceHTML) {
+  NamespaceInfo I;
+  I.Name = "Namespace";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.ChildNamespaces.emplace_back(EmptySID, "ChildNamespace",
+ InfoType::IT_namespace);
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+namespace Namespace
+
+  namespace Namespace
+  Namespaces
+  
+ChildNamespace
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitRecordHTML) {
+  RecordInfo I;
+  I.Name = "r";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.Members.emplace_back("int", "X", AccessSpecifier::AS_private);
+  I.TagType = TagTypeKind::TTK_Class;
+  I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
+  I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
+
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+class r
+
+  class r
+  
+Defined at line 10 of test.cpp
+  
+  
+Inherits from F, G
+  
+  Members
+  
+private int X
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitFunctionHTML) {
+  FunctionInfo I;
+  I.Name = "f";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
+  I.Params.emplace_back("int", "P");
+  I.IsMethod = true;
+  I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+
+
+  f
+  
+void f(int P)
+  
+  
+Defined at line 10 of test.cpp
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitEnumHTML) {
+  EnumInfo I;
+  I.Name = "e";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.Members.emplace_back("X");
+  I.Scoped = true;
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+ 

[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-07-09 Thread Diego Astiazarán via Phabricator via cfe-commits
DiegoAstiazaran updated this revision to Diff 208739.
DiegoAstiazaran marked an inline comment as done.
DiegoAstiazaran added a comment.

Remove empty line.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857

Files:
  clang-tools-extra/clang-doc/CMakeLists.txt
  clang-tools-extra/clang-doc/Generators.cpp
  clang-tools-extra/clang-doc/Generators.h
  clang-tools-extra/clang-doc/HTMLGenerator.cpp
  clang-tools-extra/clang-doc/MDGenerator.cpp
  clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
  clang-tools-extra/unittests/clang-doc/CMakeLists.txt
  clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp

Index: clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
===
--- /dev/null
+++ clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -0,0 +1,276 @@
+//===-- clang-doc/HTMLGeneratorTest.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 {
+
+std::unique_ptr getHTMLGenerator() {
+  auto G = doc::findGeneratorByName("html");
+  if (!G)
+return nullptr;
+  return std::move(G.get());
+}
+
+TEST(HTMLGeneratorTest, emitNamespaceHTML) {
+  NamespaceInfo I;
+  I.Name = "Namespace";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.ChildNamespaces.emplace_back(EmptySID, "ChildNamespace",
+ InfoType::IT_namespace);
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+namespace Namespace
+
+  namespace Namespace
+  Namespaces
+  
+ChildNamespace
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitRecordHTML) {
+  RecordInfo I;
+  I.Name = "r";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.Members.emplace_back("int", "X", AccessSpecifier::AS_private);
+  I.TagType = TagTypeKind::TTK_Class;
+  I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
+  I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
+
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+class r
+
+  class r
+  
+Defined at line 10 of test.cpp
+  
+  
+Inherits from F, G
+  
+  Members
+  
+private int X
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitFunctionHTML) {
+  FunctionInfo I;
+  I.Name = "f";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
+  I.Params.emplace_back("int", "P");
+  I.IsMethod = true;
+  I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+
+
+  f
+  
+void f(int P)
+  
+  
+Defined at line 10 of test.cpp
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitEnumHTML) {
+  EnumInfo I;
+  I.Name = "e";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  

[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-07-09 Thread Julie Hockett via Phabricator via cfe-commits
juliehockett accepted this revision.
juliehockett added a comment.
This revision is now accepted and ready to land.

LGTM, unless Jake has further comments.




Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:503
+  }
+  // std::move(Nodes.begin(), Nodes.end(), 
std::back_inserter(MainContentNode));
+

Remove this


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-07-08 Thread Diego Astiazarán via Phabricator via cfe-commits
DiegoAstiazaran added inline comments.



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:75
+Children.emplace_back(
+llvm::make_unique(Text.str(), !InlineChildren));
+  }

jakehehrlich wrote:
> I think you can just write `Children.emplace_back(Text.str(), 
> !InlineChildren)`
I think it is necessary to explicitly pass a unique_ptr, not only the args.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-07-08 Thread Diego Astiazarán via Phabricator via cfe-commits
DiegoAstiazaran updated this revision to Diff 208527.
DiegoAstiazaran marked 5 inline comments as done.
DiegoAstiazaran added a comment.

Add helper function to move a vector's elements to another vector.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857

Files:
  clang-tools-extra/clang-doc/CMakeLists.txt
  clang-tools-extra/clang-doc/Generators.cpp
  clang-tools-extra/clang-doc/Generators.h
  clang-tools-extra/clang-doc/HTMLGenerator.cpp
  clang-tools-extra/clang-doc/MDGenerator.cpp
  clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
  clang-tools-extra/unittests/clang-doc/CMakeLists.txt
  clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp

Index: clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
===
--- /dev/null
+++ clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -0,0 +1,276 @@
+//===-- clang-doc/HTMLGeneratorTest.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 {
+
+std::unique_ptr getHTMLGenerator() {
+  auto G = doc::findGeneratorByName("html");
+  if (!G)
+return nullptr;
+  return std::move(G.get());
+}
+
+TEST(HTMLGeneratorTest, emitNamespaceHTML) {
+  NamespaceInfo I;
+  I.Name = "Namespace";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.ChildNamespaces.emplace_back(EmptySID, "ChildNamespace",
+ InfoType::IT_namespace);
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+namespace Namespace
+
+  namespace Namespace
+  Namespaces
+  
+ChildNamespace
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitRecordHTML) {
+  RecordInfo I;
+  I.Name = "r";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.Members.emplace_back("int", "X", AccessSpecifier::AS_private);
+  I.TagType = TagTypeKind::TTK_Class;
+  I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
+  I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
+
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+class r
+
+  class r
+  
+Defined at line 10 of test.cpp
+  
+  
+Inherits from F, G
+  
+  Members
+  
+private int X
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitFunctionHTML) {
+  FunctionInfo I;
+  I.Name = "f";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
+  I.Params.emplace_back("int", "P");
+  I.IsMethod = true;
+  I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+
+
+  f
+  
+void f(int P)
+  
+  
+Defined at line 10 of test.cpp
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitEnumHTML) {
+  EnumInfo I;
+  I.Name = "e";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, 

[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-07-08 Thread Jake Ehrlich via Phabricator via cfe-commits
jakehehrlich added a comment.

As in I'm not quite ready for this to land but It looks preety solid. I think 
if you respond to those comments I'll take one last look and then give an 
actual accept


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-07-08 Thread Jake Ehrlich via Phabricator via cfe-commits
jakehehrlich added a comment.

This looks good to me!




Comment at: clang-tools-extra/clang-doc/Generators.cpp:75-77
 extern volatile int YAMLGeneratorAnchorSource;
 extern volatile int MDGeneratorAnchorSource;
+extern volatile int HTMLGeneratorAnchorSource;

I don't fully understand these lines. Can you explain how they work and what 
they accomplish?




Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:75
+Children.emplace_back(
+llvm::make_unique(Text.str(), !InlineChildren));
+  }

I think you can just write `Children.emplace_back(Text.str(), !InlineChildren)`



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:310-312
+std::unique_ptr Node = genHTML(Child);
+if (Node)
+  CommentBlock->Children.emplace_back(std::move(Node));

```
for (...)  
  if (std::unique)ptr<...> Node = genHTML(Child))
CommentBlock->...
```

would be a bitmore idiomatic LLVM code. I think you used this pattern above as 
well so you should fix it there as well.



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:325
+
+  Out.emplace_back(
+  llvm::make_unique(HTMLTag::TAG_H3, EnumType + I.Name));

same thing here I think.



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:358
+
+  Out.emplace_back(llvm::make_unique(
+  HTMLTag::TAG_P, Access + I.ReturnType.Type.Name + " " + I.Name + "(" +

ditto



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:422
+if (Parents.empty())
+  Out.emplace_back(llvm::make_unique(HTMLTag::TAG_P,
+  "Inherits from " + 
VParents));

ditto



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:425
+else if (VParents.empty())
+  Out.emplace_back(llvm::make_unique(HTMLTag::TAG_P,
+  "Inherits from " + Parents));

ditto



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:428
+else
+  Out.emplace_back(llvm::make_unique(
+  HTMLTag::TAG_P, "Inherits from " + Parents + ", " + VParents));

ditto



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:432-434
+  std::vector> Members =
+  genRecordMembersBlock(I.Members);
+  std::move(Members.begin(), Members.end(), std::back_inserter(Out));

You use this a lot here and once or twice above. You could write a template 
function that takes an `std::vector&&` and moves its contents into some 
other `std::vector&` where B : A

You can use SFINAE to ensure that B is subtype of A.





Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:472-475
+std::vector> Nodes =
+genHTML(*static_cast(I), InfoTitle);
+std::move(Nodes.begin(), Nodes.end(),
+  std::back_inserter(MainContentNode->Children));

These are all cases of what I was talking about before.



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:505
+
+  F.Children.emplace_back(
+  llvm::make_unique(HTMLTag::TAG_TITLE, InfoTitle));

ditto.



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:507
+  llvm::make_unique(HTMLTag::TAG_TITLE, InfoTitle));
+  F.Children.push_back(std::move(MainContentNode));
+

Use `emplace_back` when moving to avoid extra constructor calls.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-06-28 Thread Diego Astiazarán via Phabricator via cfe-commits
DiegoAstiazaran updated this revision to Diff 207174.
DiegoAstiazaran marked 2 inline comments as done.
DiegoAstiazaran added a comment.

Add a variable to use as a reference to the last item in a vector instead of 
doing vector.back().


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857

Files:
  clang-tools-extra/clang-doc/CMakeLists.txt
  clang-tools-extra/clang-doc/Generators.cpp
  clang-tools-extra/clang-doc/Generators.h
  clang-tools-extra/clang-doc/HTMLGenerator.cpp
  clang-tools-extra/clang-doc/MDGenerator.cpp
  clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
  clang-tools-extra/unittests/clang-doc/CMakeLists.txt
  clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp

Index: clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
===
--- /dev/null
+++ clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -0,0 +1,276 @@
+//===-- clang-doc/HTMLGeneratorTest.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 {
+
+std::unique_ptr getHTMLGenerator() {
+  auto G = doc::findGeneratorByName("html");
+  if (!G)
+return nullptr;
+  return std::move(G.get());
+}
+
+TEST(HTMLGeneratorTest, emitNamespaceHTML) {
+  NamespaceInfo I;
+  I.Name = "Namespace";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.ChildNamespaces.emplace_back(EmptySID, "ChildNamespace",
+ InfoType::IT_namespace);
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+namespace Namespace
+
+  namespace Namespace
+  Namespaces
+  
+ChildNamespace
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitRecordHTML) {
+  RecordInfo I;
+  I.Name = "r";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.Members.emplace_back("int", "X", AccessSpecifier::AS_private);
+  I.TagType = TagTypeKind::TTK_Class;
+  I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
+  I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
+
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+class r
+
+  class r
+  
+Defined at line 10 of test.cpp
+  
+  
+Inherits from F, G
+  
+  Members
+  
+private int X
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitFunctionHTML) {
+  FunctionInfo I;
+  I.Name = "f";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
+  I.Params.emplace_back("int", "P");
+  I.IsMethod = true;
+  I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+
+
+  f
+  
+void f(int P)
+  
+  
+Defined at line 10 of test.cpp
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitEnumHTML) {
+  EnumInfo I;
+  I.Name = "e";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  

[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-06-28 Thread Jake Ehrlich via Phabricator via cfe-commits
jakehehrlich added inline comments.



Comment at: clang-tools-extra/clang-doc/HTMLGenerator.cpp:228
+  Out.emplace_back(llvm::make_unique(HTMLTag::TAG_H2, "Functions"));
+  Out.emplace_back(llvm::make_unique(HTMLTag::TAG_DIV));
+  for (const auto  : Functions) {

Refering to this as `Out.back()` is confusing, can you give it a variable name? 
It took me longer than I care to admit to figure out that you weren't appending 
to `Out` in the loop. A pretty common pattern I use is to just assign `back()` 
to a reference that I'm going to use a lot.

```
Out.emplace_back(...);
auto& DivBody = Out.back();
```

That way you get the inplace construction and you can refer to it wherever 
you'd like by name.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D63857: [clang-doc] Add a structured HTML generator

2019-06-28 Thread Diego Astiazarán via Phabricator via cfe-commits
DiegoAstiazaran updated this revision to Diff 207160.
DiegoAstiazaran retitled this revision from "[clang-doc] Structured HTML 
generator" to "[clang-doc] Add a structured HTML generator".
DiegoAstiazaran edited the summary of this revision.
DiegoAstiazaran added a comment.
Herald added subscribers: kadircet, arphaman, mgorny.

This patch depended on D63180 , that revision 
has been abandoned and combined with this one.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D63857/new/

https://reviews.llvm.org/D63857

Files:
  clang-tools-extra/clang-doc/CMakeLists.txt
  clang-tools-extra/clang-doc/Generators.cpp
  clang-tools-extra/clang-doc/Generators.h
  clang-tools-extra/clang-doc/HTMLGenerator.cpp
  clang-tools-extra/clang-doc/MDGenerator.cpp
  clang-tools-extra/clang-doc/tool/ClangDocMain.cpp
  clang-tools-extra/unittests/clang-doc/CMakeLists.txt
  clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp

Index: clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
===
--- /dev/null
+++ clang-tools-extra/unittests/clang-doc/HTMLGeneratorTest.cpp
@@ -0,0 +1,276 @@
+//===-- clang-doc/HTMLGeneratorTest.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 {
+
+std::unique_ptr getHTMLGenerator() {
+  auto G = doc::findGeneratorByName("html");
+  if (!G)
+return nullptr;
+  return std::move(G.get());
+}
+
+TEST(HTMLGeneratorTest, emitNamespaceHTML) {
+  NamespaceInfo I;
+  I.Name = "Namespace";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.ChildNamespaces.emplace_back(EmptySID, "ChildNamespace",
+ InfoType::IT_namespace);
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+namespace Namespace
+
+  namespace Namespace
+  Namespaces
+  
+ChildNamespace
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitRecordHTML) {
+  RecordInfo I;
+  I.Name = "r";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.Members.emplace_back("int", "X", AccessSpecifier::AS_private);
+  I.TagType = TagTypeKind::TTK_Class;
+  I.Parents.emplace_back(EmptySID, "F", InfoType::IT_record);
+  I.VirtualParents.emplace_back(EmptySID, "G", InfoType::IT_record);
+
+  I.ChildRecords.emplace_back(EmptySID, "ChildStruct", InfoType::IT_record);
+  I.ChildFunctions.emplace_back();
+  I.ChildFunctions.back().Name = "OneFunction";
+  I.ChildEnums.emplace_back();
+  I.ChildEnums.back().Name = "OneEnum";
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+class r
+
+  class r
+  
+Defined at line 10 of test.cpp
+  
+  
+Inherits from F, G
+  
+  Members
+  
+private int X
+  
+  Records
+  
+ChildStruct
+  
+  Functions
+  
+OneFunction
+
+   OneFunction()
+
+  
+  Enums
+  
+enum OneEnum
+  
+
+)raw";
+
+  EXPECT_EQ(Expected, Actual.str());
+}
+
+TEST(HTMLGeneratorTest, emitFunctionHTML) {
+  FunctionInfo I;
+  I.Name = "f";
+  I.Namespace.emplace_back(EmptySID, "A", InfoType::IT_namespace);
+
+  I.DefLoc = Location(10, llvm::SmallString<16>{"test.cpp"});
+  I.Loc.emplace_back(12, llvm::SmallString<16>{"test.cpp"});
+
+  I.ReturnType = TypeInfo(EmptySID, "void", InfoType::IT_default);
+  I.Params.emplace_back("int", "P");
+  I.IsMethod = true;
+  I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record);
+
+  auto G = getHTMLGenerator();
+  assert(G);
+  std::string Buffer;
+  llvm::raw_string_ostream Actual(Buffer);
+  auto Err = G->generateDocForInfo(, Actual);
+  assert(!Err);
+  std::string Expected = R"raw(
+
+
+
+  f
+  
+void f(int P)
+  
+  
+Defined at line 10 of test.cpp
+  
+
+)raw";
+
+  EXPECT_EQ(Expected,