[clang-doc] Remove Markdown library implementation#209257
Merged
Merged
Conversation
The current implementation is unsatisfactory in many ways, and it is now unclear if development of this library will continue any time soon. To reduce maintenance and build cost, we should just remove it now before the branch point, and come up with a more thoughtful design that addresses the requirements for clang and clang-doc more completely. This reverts commit cc048e8 and commit b6976d2.
|
@llvm/pr-subscribers-clang-tools-extra Author: Paul Kirth (ilovepi) ChangesThe current implementation is unsatisfactory in many ways, and it is now unclear if development of this library will continue any time soon. To reduce maintenance and build cost, we should just remove it now before the branch point, and come up with a more thoughtful design that addresses the requirements for clang and clang-doc more completely. This reverts commit cc048e8 and commit b6976d2. Full diff: https://github.com/llvm/llvm-project/pull/209257.diff 6 Files Affected:
diff --git a/clang-tools-extra/clang-doc/CMakeLists.txt b/clang-tools-extra/clang-doc/CMakeLists.txt
index 438888c1e5e13..22e2c8159e9f6 100644
--- a/clang-tools-extra/clang-doc/CMakeLists.txt
+++ b/clang-tools-extra/clang-doc/CMakeLists.txt
@@ -4,7 +4,6 @@ set(LLVM_LINK_COMPONENTS
FrontendOpenMP
)
add_subdirectory(support)
-add_subdirectory(markdown)
add_clang_library(clangDoc STATIC
BitcodeReader.cpp
diff --git a/clang-tools-extra/clang-doc/markdown/CMakeLists.txt b/clang-tools-extra/clang-doc/markdown/CMakeLists.txt
deleted file mode 100644
index 11e6958e2e828..0000000000000
--- a/clang-tools-extra/clang-doc/markdown/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-set(LLVM_LINK_COMPONENTS
- Support
- )
-
-add_clang_library(clangDocMarkdown STATIC
- Markdown.cpp
- )
diff --git a/clang-tools-extra/clang-doc/markdown/Markdown.cpp b/clang-tools-extra/clang-doc/markdown/Markdown.cpp
deleted file mode 100644
index e7049822543c1..0000000000000
--- a/clang-tools-extra/clang-doc/markdown/Markdown.cpp
+++ /dev/null
@@ -1,99 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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 "Markdown.h"
-
-namespace clang::doc::markdown {
-
-// TODO: print() currently outputs nodes flat with no indentation. Add
-// S-expression style formatting (as used by the Swift AST printer) to make
-// dumped trees easier to read.
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-LLVM_DUMP_METHOD void InlineNode::dump() const { print(llvm::errs()); }
-#endif
-
-void TextNode::print(llvm::raw_ostream &OS) const {
- OS << "TextNode: " << getText() << "\n";
-}
-
-void InlineCodeNode::print(llvm::raw_ostream &OS) const {
- OS << "InlineCodeNode: " << getCode() << "\n";
-}
-
-void EmphasisNode::print(llvm::raw_ostream &OS) const {
- OS << "EmphasisNode\n";
- for (const auto &Child : children())
- Child.print(OS);
-}
-
-void StrongNode::print(llvm::raw_ostream &OS) const {
- OS << "StrongNode\n";
- for (const auto &Child : children())
- Child.print(OS);
-}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-LLVM_DUMP_METHOD void BlockNode::dump() const { print(llvm::errs()); }
-#endif
-
-void ParagraphNode::print(llvm::raw_ostream &OS) const {
- OS << "ParagraphNode\n";
- for (const auto &Child : children())
- Child.print(OS);
-}
-
-void HeadingNode::print(llvm::raw_ostream &OS) const {
- OS << "HeadingNode: level=" << getLevel() << "\n";
- for (const auto &Child : children())
- Child.print(OS);
-}
-
-void FencedCodeNode::print(llvm::raw_ostream &OS) const {
- OS << "FencedCodeNode: lang=" << getLang() << "\n" << getCode() << "\n";
-}
-
-void ListItemNode::print(llvm::raw_ostream &OS) const {
- OS << "ListItemNode\n";
- for (const auto &Child : children())
- Child.print(OS);
-}
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
-LLVM_DUMP_METHOD void ListItemNode::dump() const { print(llvm::errs()); }
-#endif
-
-void UnorderedListNode::print(llvm::raw_ostream &OS) const {
- OS << "UnorderedListNode\n";
- for (const auto &Item : items())
- Item.print(OS);
-}
-
-void OrderedListNode::print(llvm::raw_ostream &OS) const {
- OS << "OrderedListNode: start=" << getStart() << "\n";
- for (const auto &Item : items())
- Item.print(OS);
-}
-
-void BlockQuoteNode::print(llvm::raw_ostream &OS) const {
- OS << "BlockQuoteNode\n";
- for (const auto &Child : children())
- Child.print(OS);
-}
-
-void ThematicBreakNode::print(llvm::raw_ostream &OS) const {
- OS << "ThematicBreakNode\n";
-}
-
-void DocumentNode::print(llvm::raw_ostream &OS) const {
- OS << "DocumentNode\n";
- for (const auto &Child : children())
- Child.print(OS);
-}
-
-} // namespace clang::doc::markdown
diff --git a/clang-tools-extra/clang-doc/markdown/Markdown.h b/clang-tools-extra/clang-doc/markdown/Markdown.h
deleted file mode 100644
index 39c37cec9a774..0000000000000
--- a/clang-tools-extra/clang-doc/markdown/Markdown.h
+++ /dev/null
@@ -1,315 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// Defines the Markdown AST node hierarchy for the clang-doc Markdown parser.
-///
-/// Block nodes represent structural constructs (paragraphs, headings, lists,
-/// fenced code blocks, etc). Inline nodes represent span-level content (text,
-/// emphasis, inline code) that appears inside block nodes.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_MARKDOWN_MARKDOWN_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_MARKDOWN_MARKDOWN_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/simple_ilist.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace clang::doc::markdown {
-
-enum class NodeKind {
- // Inline nodes
- NK_Text,
- NK_InlineCode,
- NK_Emphasis,
- NK_Strong,
- // Block nodes
- NK_Paragraph,
- NK_Heading,
- NK_FencedCode,
- NK_Table, // TODO: add TableNode
- NK_UnorderedList,
- NK_OrderedList,
- NK_BlockQuote,
- NK_ThematicBreak,
- NK_Document,
-};
-
-/// Base class for all inline nodes. Inline nodes represent span-level content
-/// such as text, emphasis, and inline code.
-class InlineNode : public llvm::ilist_node<InlineNode> {
-public:
- explicit InlineNode(NodeKind K) : Kind(K) {}
- virtual ~InlineNode() = default;
- NodeKind getKind() const { return Kind; }
-
- /// Recursively prints the node and its children to OS.
- virtual void print(llvm::raw_ostream &OS) const = 0;
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- /// Prints to llvm::errs(). Only available in assert builds.
- LLVM_DUMP_METHOD void dump() const;
-#endif
-
-private:
- NodeKind Kind;
-};
-
-using InlineList = llvm::simple_ilist<InlineNode>;
-
-/// A plain text run.
-class TextNode : public InlineNode {
-public:
- explicit TextNode(llvm::StringRef T)
- : InlineNode(NodeKind::NK_Text), Text(T) {}
- llvm::StringRef getText() const { return Text; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const InlineNode *N) {
- return N->getKind() == NodeKind::NK_Text;
- }
-
-private:
- llvm::StringRef Text;
-};
-
-/// A backtick-delimited inline code span.
-class InlineCodeNode : public InlineNode {
-public:
- explicit InlineCodeNode(llvm::StringRef C)
- : InlineNode(NodeKind::NK_InlineCode), Code(C) {}
- llvm::StringRef getCode() const { return Code; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const InlineNode *N) {
- return N->getKind() == NodeKind::NK_InlineCode;
- }
-
-private:
- llvm::StringRef Code;
-};
-
-/// An emphasis span (* or _).
-class EmphasisNode : public InlineNode {
-public:
- EmphasisNode() : InlineNode(NodeKind::NK_Emphasis) {}
- void addChild(InlineNode &N) { Children.push_back(N); }
- void removeChild(InlineNode &N) { Children.remove(N); }
- InlineList &children() { return Children; }
- const InlineList &children() const { return Children; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const InlineNode *N) {
- return N->getKind() == NodeKind::NK_Emphasis;
- }
-
-private:
- InlineList Children;
-};
-
-/// A strong emphasis span (** or __).
-class StrongNode : public InlineNode {
-public:
- StrongNode() : InlineNode(NodeKind::NK_Strong) {}
- void addChild(InlineNode &N) { Children.push_back(N); }
- void removeChild(InlineNode &N) { Children.remove(N); }
- InlineList &children() { return Children; }
- const InlineList &children() const { return Children; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const InlineNode *N) {
- return N->getKind() == NodeKind::NK_Strong;
- }
-
-private:
- InlineList Children;
-};
-
-/// Base class for all block nodes. Block nodes represent structural constructs
-/// such as paragraphs, headings, and lists.
-class BlockNode : public llvm::ilist_node<BlockNode> {
-public:
- explicit BlockNode(NodeKind K) : Kind(K) {}
- virtual ~BlockNode() = default;
- NodeKind getKind() const { return Kind; }
-
- /// Recursively prints the node and its children to OS.
- virtual void print(llvm::raw_ostream &OS) const = 0;
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- /// Prints to llvm::errs(). Only available in assert builds.
- LLVM_DUMP_METHOD void dump() const;
-#endif
-
-private:
- NodeKind Kind;
-};
-
-using BlockList = llvm::simple_ilist<BlockNode>;
-
-/// A paragraph of inline content.
-class ParagraphNode : public BlockNode {
-public:
- ParagraphNode() : BlockNode(NodeKind::NK_Paragraph) {}
- void addChild(InlineNode &N) { Children.push_back(N); }
- void removeChild(InlineNode &N) { Children.remove(N); }
- InlineList &children() { return Children; }
- const InlineList &children() const { return Children; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const BlockNode *N) {
- return N->getKind() == NodeKind::NK_Paragraph;
- }
-
-private:
- InlineList Children;
-};
-
-/// An ATX heading (# through ######).
-class HeadingNode : public BlockNode {
-public:
- explicit HeadingNode(unsigned L)
- : BlockNode(NodeKind::NK_Heading), Level(L) {}
- unsigned getLevel() const { return Level; }
- void addChild(InlineNode &N) { Children.push_back(N); }
- void removeChild(InlineNode &N) { Children.remove(N); }
- InlineList &children() { return Children; }
- const InlineList &children() const { return Children; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const BlockNode *N) {
- return N->getKind() == NodeKind::NK_Heading;
- }
-
-private:
- unsigned Level;
- InlineList Children;
-};
-
-/// A fenced code block (``` or ~~~). Lang holds the info string.
-class FencedCodeNode : public BlockNode {
-public:
- FencedCodeNode(llvm::StringRef L, llvm::StringRef C)
- : BlockNode(NodeKind::NK_FencedCode), Lang(L), Code(C) {}
- llvm::StringRef getLang() const { return Lang; }
- llvm::StringRef getCode() const { return Code; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const BlockNode *N) {
- return N->getKind() == NodeKind::NK_FencedCode;
- }
-
-private:
- llvm::StringRef Lang;
- llvm::StringRef Code;
-};
-
-/// A single item in an unordered or ordered list.
-/// ListItemNode is not a BlockNode -- it only lives inside list nodes.
-class ListItemNode : public llvm::ilist_node<ListItemNode> {
-public:
- ListItemNode() = default;
- void addChild(InlineNode &N) { Children.push_back(N); }
- void removeChild(InlineNode &N) { Children.remove(N); }
- InlineList &children() { return Children; }
- const InlineList &children() const { return Children; }
- void print(llvm::raw_ostream &OS) const;
-
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- /// Prints to llvm::errs(). Only available in assert builds.
- /// ListItemNode provides its own dump() since it does not inherit BlockNode.
- LLVM_DUMP_METHOD void dump() const;
-#endif
-
-private:
- InlineList Children;
-};
-
-using ItemList = llvm::simple_ilist<ListItemNode>;
-
-/// An unordered list (-, *, or + markers).
-class UnorderedListNode : public BlockNode {
-public:
- UnorderedListNode() : BlockNode(NodeKind::NK_UnorderedList) {}
- void addItem(ListItemNode &N) { Items.push_back(N); }
- void removeItem(ListItemNode &N) { Items.remove(N); }
- ItemList &items() { return Items; }
- const ItemList &items() const { return Items; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const BlockNode *N) {
- return N->getKind() == NodeKind::NK_UnorderedList;
- }
-
-private:
- ItemList Items;
-};
-
-/// An ordered list (1. 2. 3. markers). Start holds the first item number.
-class OrderedListNode : public BlockNode {
-public:
- explicit OrderedListNode(unsigned S = 1)
- : BlockNode(NodeKind::NK_OrderedList), Start(S) {}
- unsigned getStart() const { return Start; }
- void addItem(ListItemNode &N) { Items.push_back(N); }
- void removeItem(ListItemNode &N) { Items.remove(N); }
- ItemList &items() { return Items; }
- const ItemList &items() const { return Items; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const BlockNode *N) {
- return N->getKind() == NodeKind::NK_OrderedList;
- }
-
-private:
- unsigned Start;
- ItemList Items;
-};
-
-/// A block quote (> marker).
-class BlockQuoteNode : public BlockNode {
-public:
- BlockQuoteNode() : BlockNode(NodeKind::NK_BlockQuote) {}
- void addChild(BlockNode &N) { Children.push_back(N); }
- void removeChild(BlockNode &N) { Children.remove(N); }
- BlockList &children() { return Children; }
- const BlockList &children() const { return Children; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const BlockNode *N) {
- return N->getKind() == NodeKind::NK_BlockQuote;
- }
-
-private:
- BlockList Children;
-};
-
-/// A thematic break (---, ***, or ___).
-class ThematicBreakNode : public BlockNode {
-public:
- ThematicBreakNode() : BlockNode(NodeKind::NK_ThematicBreak) {}
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const BlockNode *N) {
- return N->getKind() == NodeKind::NK_ThematicBreak;
- }
-};
-
-/// The root document node. Contains all top-level block nodes.
-class DocumentNode : public BlockNode {
-public:
- DocumentNode() : BlockNode(NodeKind::NK_Document) {}
- void addChild(BlockNode &N) { Children.push_back(N); }
- void removeChild(BlockNode &N) { Children.remove(N); }
- BlockList &children() { return Children; }
- const BlockList &children() const { return Children; }
- void print(llvm::raw_ostream &OS) const override;
- static bool classof(const BlockNode *N) {
- return N->getKind() == NodeKind::NK_Document;
- }
-
-private:
- BlockList Children;
-};
-
-} // namespace clang::doc::markdown
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_DOC_MARKDOWN_MARKDOWN_H
diff --git a/clang-tools-extra/unittests/clang-doc/CMakeLists.txt b/clang-tools-extra/unittests/clang-doc/CMakeLists.txt
index 97a26f0e24d09..01b34ec9a791e 100644
--- a/clang-tools-extra/unittests/clang-doc/CMakeLists.txt
+++ b/clang-tools-extra/unittests/clang-doc/CMakeLists.txt
@@ -31,7 +31,6 @@ add_extra_unittest(ClangDocTests
SerializeTest.cpp
YAMLGeneratorTest.cpp
JSONGeneratorTest.cpp
- MarkdownParserTest.cpp
)
clang_target_link_libraries(ClangDocTests
@@ -50,6 +49,5 @@ clang_target_link_libraries(ClangDocTests
target_link_libraries(ClangDocTests
PRIVATE
clangDoc
- clangDocMarkdown
LLVMTestingSupport
)
diff --git a/clang-tools-extra/unittests/clang-doc/MarkdownParserTest.cpp b/clang-tools-extra/unittests/clang-doc/MarkdownParserTest.cpp
deleted file mode 100644
index 3bc3dfd852f3e..0000000000000
--- a/clang-tools-extra/unittests/clang-doc/MarkdownParserTest.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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 "markdown/Markdown.h"
-#include "gtest/gtest.h"
-
-using namespace clang::doc::markdown;
-using namespace llvm;
-
-namespace {
-
-/// Returns the text of the first TextNode child in the given inline list.
-static llvm::StringRef firstChildText(const InlineList &L) {
- return llvm::cast<TextNode>(L.front()).getText();
-}
-
-TEST(MarkdownNodeTest, TextNode) {
- TextNode N("hello");
- EXPECT_EQ(N.getKind(), NodeKind::NK_Text);
- EXPECT_EQ(N.getText(), "hello");
-}
-
-TEST(MarkdownNodeTest, FencedCodeNode) {
- FencedCodeNode N("cpp", "int x = 0;\nint y = 1;");
- EXPECT_EQ(N.getKind(), NodeKind::NK_FencedCode);
- EXPECT_EQ(N.getLang(), "cpp");
- llvm::SmallVector<llvm::StringRef> Lines;
- N.getCode().split(Lines, '\n');
- EXPECT_EQ(Lines[0], "int x = 0;");
- EXPECT_EQ(Lines[1], "int y = 1;");
-}
-
-TEST(MarkdownNodeTest, HeadingNode) {
- HeadingNode N(2);
- EXPECT_EQ(N.getKind(), NodeKind::NK_Heading);
- EXPECT_EQ(N.getLevel(), 2u);
-}
-
-TEST(MarkdownNodeTest, ThematicBreakNode) {
- ThematicBreakNode N;
- EXPECT_EQ(N.getKind(), NodeKind::NK_ThematicBreak);
-}
-
-TEST(MarkdownNodeTest, InlineCodeNode) {
- InlineCodeNode N("foo()");
- EXPECT_EQ(N.getKind(), NodeKind::NK_InlineCode);
- EXPECT_EQ(N.getCode(), "foo()");
-}
-
-TEST(MarkdownNodeTest, EmphasisNode) {
- EmphasisNode N;
- TextNode Child("emphasized");
- N.addChild(Child);
- EXPECT_EQ(N.getKind(), NodeKind::NK_Emphasis);
- EXPECT_FALSE(N.children().empty());
- EXPECT_EQ(firstChildText(N.children()), "emphasized");
-}
-
-TEST(MarkdownNodeTest, EmphasisRemoveChild) {
- EmphasisNode N;
- TextNode Child("temp");
- N.addChild(Child);
- EXPECT_FALSE(N.children().empty());
- N.removeChild(Child);
- EXPECT_TRUE(N.children().empty());
-}
-
-TEST(MarkdownNodeTest, UnorderedListNode) {
- UnorderedListNode N;
- EXPECT_EQ(N.getKind(), NodeKind::NK_UnorderedList);
- EXPECT_TRUE(N.items().empty());
-}
-
-TEST(MarkdownNodeTest, UnorderedListRemoveItem) {
- UnorderedListNode List;
- ListItemNode Item;
- List.addItem(Item);
- EXPECT_FALSE(List.items().empty());
- List.removeItem(Item);
- EXPECT_TRUE(List.items().empty());
-}
-
-TEST(MarkdownNodeTest, ParagraphNode) {
- ParagraphNode N;
- EXPECT_EQ(N.getKind(), NodeKind::NK_Paragraph);
- EXPECT_TRUE(N.children().empty());
-}
-
-TEST(MarkdownNodeTest, DocumentNode) {
- DocumentNode N;
- EXPECT_EQ(N.getKind(), NodeKind::NK_Document);
- EXPECT_TRUE(N.children().empty());
-}
-
-TEST(MarkdownNodeTest, ParagraphWithChildren) {
- ParagraphNode Para;
- TextNode Child("hello");
- Para.addChild(Child);
- EXPECT_FALSE(Para.children().empty());
- EXPECT_EQ(firstChildText(Para.children()), "hello");
-}
-
-TEST(MarkdownNodeTest, UnorderedListWithItems) {
- UnorderedListNode List;
- ListItemNode Item;
- TextNode Child("item text");
- Item.addChild(Child);
- List.addItem(Item);
- EXPECT_FALSE(List.items().empty());
- EXPECT_EQ(firstChildText(List.items().front().children()), "item text");
-}
-
-} // namespace
|
Contributor
Author
|
To be clear there are no users of this code yet, other than tests. The plan was to have this evolve over the summer, but that will no longer happen due to changes in resourcing and availability. |
evelez7
approved these changes
Jul 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The current implementation is unsatisfactory in many ways, and it is now unclear if development of this library will continue any time soon. To reduce maintenance and build cost, we should just remove it now before the branch point, and come up with a more thoughtful design that addresses the requirements for clang and clang-doc more completely.
This reverts commit cc048e8 and commit b6976d2.