diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4ddb36ac4..2864794650 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ concurrency: jobs: cpp-matrix: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 name: Generate Test Matrix outputs: matrix: ${{ steps.cpp-matrix.outputs.matrix }} @@ -640,8 +640,6 @@ jobs: "html" ) - cp example/external/url/mrdocs.yml boost/libs/url/doc/mrdocs.yml - # Generate the demos for each variant and generator for variant in single multi; do for generator in "${generators[@]}"; do diff --git a/example/external/url/mrdocs.yml b/example/external/url/mrdocs.yml deleted file mode 100644 index a3d27a41fc..0000000000 --- a/example/external/url/mrdocs.yml +++ /dev/null @@ -1,66 +0,0 @@ -# Input -source-root: .. -# Directories that contain documented source files -input: - - ../include -# Patterns to filter out the source-files in the directories -file-patterns: - - '*.hpp' - -# Filters -include-symbols: - - 'boost::urls::**' -exclude-symbols: -implementation-defined: - - 'boost::urls::detail' - - 'boost::urls::**::detail' - - 'boost::urls::*_unsafe' - - 'boost::urls::*_t' - - 'boost::urls::make_error_code' - - 'boost::urls::make_void' - - 'boost::urls::implementation_defined' - - 'boost::urls::grammar::implementation_defined' - - 'boost::urls::string_token::implementation_defined' - - 'boost::urls::grammar::*_t' - - 'boost::urls::grammar::make_error_*' - - 'boost::urls::grammar::operator_*' - - 'boost::urls::string_token::*_t' -see-below: - - 'boost::urls::see_below' - - 'boost::urls::grammar::see_below' - - 'boost::urls::string_token::see_below' - -# Metadata Extraction -private-bases: false - -# Generator -generate: adoc -base-url: https://www.github.com/boostorg/url/blob/develop/include/ # boost/url/url_view.hpp - -# Style -verbose: true -multipage: true - -# The target for MrDocs simply includes all symbols defined in all -# headers with the appropriate compilation options. -# Nothing else should be included in the MrDocs configuration or -# would be useful to MrDocs. -# -# This single source file not only includes all symbols (the source -# files do not collectively include all headers) but also makes MrDocs -# run much faster than relying on the entire library. -# -# The time to extract the declarations went from ~8m6s to ~3s in our -# experiments: a 162x speedup while including all symbols! -# -# In practice, this special target is simply emulating the -# default behavior of the standardese tool with MrDocs, which -# requires the user to clearly specify the targets via the -# compilation database. -# -# The BOOST_URL_MRDOCS_BUILD=ON is the only option we usually need -# here. -# The other options are set just to ensure other targets are -# ignored even if these options are set as ON in the cache. -# -cmake: '-D BOOST_URL_MRDOCS_BUILD=ON -D CMAKE_CXX_STANDARD=20 -D BOOST_URL_BUILD_FUZZERS=OFF -D BOOST_URL_BUILD_EXAMPLES=OFF -D BOOST_URL_BUILD_TESTS=OFF -D BUILD_TESTING=OFF' diff --git a/src/lib/AST/ParseJavadoc.cpp b/src/lib/AST/ParseJavadoc.cpp index 12e57993ce..fcb800c902 100644 --- a/src/lib/AST/ParseJavadoc.cpp +++ b/src/lib/AST/ParseJavadoc.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable: 5054) // C5054: operator '+': deprecated between enumerations of different types @@ -33,6 +35,52 @@ #include #include +#ifdef NDEBUG +#define MRDOCS_COMMENT_TRACE(D, C) +#else + +# define MRDOCS_COMMENT_TRACE_MERGE_(a, b) a##b +# define MRDOCS_COMMENT_TRACE_LABEL_(a) MRDOCS_COMMENT_TRACE_MERGE_(comment_content_, a) +# define MRDOCS_COMMENT_TRACE_UNIQUE_NAME MRDOCS_COMMENT_TRACE_LABEL_(__LINE__) + +namespace detail { + template + void + dumpCommentContent(T const* C, clang::ASTContext const& Ctx, llvm::SmallString<1024>& contents) + { + if (!C) + { + return; + } + llvm::raw_svector_ostream os(contents); + if constexpr (std::derived_from) + { + auto const* CC = static_cast(C); + clang::SourceRange const R = CC->getSourceRange(); + clang::SourceManager const& SM = Ctx.getSourceManager(); + contents = clang::Lexer::getSourceText( + clang::CharSourceRange::getTokenRange(R), + SM, + Ctx.getLangOpts()); + } + } + + template + requires (!std::is_pointer_v) + void + dumpCommentContent(T const& C, clang::ASTContext const& Ctx, llvm::SmallString<1024>& contents) + { + dumpCommentContent(&C, Ctx, contents); + } +} // namespace detail + +#define MRDOCS_COMMENT_TRACE(D, C) \ + SmallString<1024> MRDOCS_COMMENT_TRACE_UNIQUE_NAME; \ + ::detail::dumpCommentContent(D, C, MRDOCS_COMMENT_TRACE_UNIQUE_NAME); \ + report::debug("{}", std::string_view(MRDOCS_COMMENT_TRACE_UNIQUE_NAME.str())) +#endif + + /* AST Types Comment @@ -509,10 +557,12 @@ JavadocVisitor:: visitChildren( Comment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); ScopeExitRestore s1(it_, C->child_begin()); ScopeExitRestore s2(end_, C->child_end()); while(it_ != end_) { + MRDOCS_COMMENT_TRACE(*it_, ctx_); visit(*it_); ++it_; // must happen after } @@ -597,6 +647,7 @@ Javadoc JavadocVisitor:: build() { + MRDOCS_COMMENT_TRACE(FC_, ctx_); visit(FC_); return std::move(jd_); } @@ -606,6 +657,7 @@ JavadocVisitor:: visitComment( Comment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); visitChildren(C); } @@ -620,6 +672,7 @@ JavadocVisitor:: visitTextComment( TextComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); llvm::StringRef s = C->getText(); // If this is the first text comment in the // paragraph then remove all the leading space. @@ -642,6 +695,7 @@ Expected JavadocVisitor:: parseHTMLTag(HTMLStartTagComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); TagComponents res; res.tag = C->getTagName().str(); @@ -700,6 +754,7 @@ JavadocVisitor:: visitHTMLStartTagComment( HTMLStartTagComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); MRDOCS_ASSERT(C->child_begin() == C->child_end()); PresumedLoc const loc = sm_.getPresumedLoc(C->getBeginLoc()); auto filename = files::makePosixStyle(loc.getFilename()); @@ -766,6 +821,7 @@ JavadocVisitor:: visitHTMLEndTagComment( HTMLEndTagComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); MRDOCS_ASSERT(C->child_begin() == C->child_end()); --htmlTagNesting_; } @@ -923,6 +979,7 @@ JavadocVisitor:: visitInlineCommandComment( InlineCommandComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); auto const* cmd = ctx_ .getCommentCommandTraits() .getCommandInfo(C->getCommandID()); @@ -1074,6 +1131,7 @@ JavadocVisitor:: visitParagraphComment( ParagraphComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); if(block_) return visitChildren(C); doc::Paragraph paragraph; @@ -1089,6 +1147,7 @@ JavadocVisitor:: visitBlockCommandComment( BlockCommandComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); auto const* cmd = ctx_ .getCommentCommandTraits() .getCommandInfo(C->getCommandID()); @@ -1174,24 +1233,26 @@ visitBlockCommandComment( doc::Paragraph paragraph; auto scope = enterScope(paragraph); visitChildren(C->getParagraph()); - if(! paragraph.children.empty()) + if (C->getNumArgs() > 0) { - if (C->getNumArgs() > 0) - { - jd_.emplace_back(doc::Heading(C->getArgText(0).str())); - } - else + jd_.emplace_back(doc::Heading(C->getArgText(0).str())); + } + if (!paragraph.children.empty()) + { + // the first TextComment is the heading text + if (C->getNumArgs() == 0) { - // the first TextComment is the heading text doc::String text(std::move( paragraph.children.front()->string)); // VFALCO Unfortunately clang puts at least // one space in front of the text, which seems // incorrect. - auto const s = trim(text); - if(s.size() != text.size()) + if (auto const s = trim(text); + s.size() != text.size()) + { text = s; + } doc::Heading heading(std::move(text)); jd_.emplace_back(std::move(heading)); @@ -1200,8 +1261,10 @@ visitBlockCommandComment( paragraph.children.erase(paragraph.children.begin()); } - if(! paragraph.children.empty()) + if (!paragraph.children.empty()) + { jd_.emplace_back(std::move(paragraph)); + } } return; } @@ -1451,6 +1514,7 @@ JavadocVisitor:: visitParamCommandComment( ParamCommandComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); doc::Param param; if(C->hasParamName()) { @@ -1494,6 +1558,7 @@ JavadocVisitor:: visitTParamCommandComment( TParamCommandComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); doc::TParam tparam; if(C->hasParamName()) { @@ -1534,6 +1599,7 @@ JavadocVisitor:: visitVerbatimBlockComment( VerbatimBlockComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); doc::Code code; auto scope = enterScope(code); //if(C->hasNonWhitespaceParagraph()) @@ -1546,6 +1612,7 @@ JavadocVisitor:: visitVerbatimLineComment( VerbatimLineComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); // VFALCO This doesn't seem to be used // in any of my codebases, follow up } @@ -1555,6 +1622,7 @@ JavadocVisitor:: visitVerbatimBlockLineComment( VerbatimBlockLineComment const* C) { + MRDOCS_COMMENT_TRACE(C, ctx_); emplaceText(true, C->getText().str()); } @@ -1565,6 +1633,7 @@ JavadocVisitor:: goodArgCount(std::size_t n, InlineCommandComment const& C) { + MRDOCS_COMMENT_TRACE(C, ctx_); if(C.getNumArgs() != n) { auto loc = sm_.getPresumedLoc(C.getBeginLoc()); @@ -1611,7 +1680,9 @@ parseJavadoc( Config const& config, Diagnostics& diags) { - auto result = JavadocVisitor(FC, D, config, diags).build(); + MRDOCS_COMMENT_TRACE(FC, D->getASTContext()); + JavadocVisitor visitor(FC, D, config, diags); + auto result = visitor.build(); if(jd == nullptr) { // Do not create javadocs which have no nodes diff --git a/test-files/golden-tests/javadoc/par-1.adoc b/test-files/golden-tests/javadoc/par-1.adoc new file mode 100644 index 0000000000..0398d07157 --- /dev/null +++ b/test-files/golden-tests/javadoc/par-1.adoc @@ -0,0 +1,166 @@ += Reference +:mrdocs: + +[#index] +== Global namespace + + +=== Functions + +[cols=2] +|=== +| Name | Description + +| <> +| Brief + + + +| <> +| Brief + + + +| <> +| Brief + + + +| <> +| Brief + + + +|=== + +[#f1] +== f1 + + +Brief + + + +=== Synopsis + + +Declared in `<par‐1.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +f1(); +---- + +=== Description + + + +=== Custom par + +Paragraph 1 + +[,cpp] +---- +void f1(); +---- + + +[#f2] +== f2 + + +Brief + + + +=== Synopsis + + +Declared in `<par‐1.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +f2(); +---- + +=== Description + + + +=== Custom par + +Paragraph 2 + +[,cpp] +---- +void f2(); +---- + + +[#f3] +== f3 + + +Brief + + + +=== Synopsis + + +Declared in `<par‐1.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +f3(); +---- + +=== Description + + + +=== Custom par + +[,cpp] +---- +void f3(); +---- + + +[#f4] +== f4 + + +Brief + + + +=== Synopsis + + +Declared in `<par‐1.cpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +f4(); +---- + +=== Description + + + +=== Custom par + +[,cpp] +---- +void f4(); +---- + + + + +[.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/javadoc/par-1.cpp b/test-files/golden-tests/javadoc/par-1.cpp new file mode 100644 index 0000000000..768c2ba68c --- /dev/null +++ b/test-files/golden-tests/javadoc/par-1.cpp @@ -0,0 +1,43 @@ +/** Brief + + @par Custom par + Paragraph 1 + + @code + void f1(); + @endcode + + */ +void f1(); + +/** Brief + + @par Custom par + + Paragraph 2 + + @code + void f2(); + @endcode + + */ +void f2(); + +/** Brief + + @par Custom par + @code + void f3(); + @endcode + */ +void f3(); + +/** Brief + + @par Custom par + + @code + void f4(); + @endcode + */ +void f4(); \ No newline at end of file diff --git a/test-files/golden-tests/javadoc/par-1.html b/test-files/golden-tests/javadoc/par-1.html new file mode 100644 index 0000000000..846612718c --- /dev/null +++ b/test-files/golden-tests/javadoc/par-1.html @@ -0,0 +1,164 @@ + + +Reference + + +
+

Reference

+
+
+

Global namespace

+
+

Functions

+ + + + + + + + + + + + + +
NameDescription
f1

Brief

+ +
f2

Brief

+ +
f3

Brief

+ +
f4

Brief

+ +
+
+
+
+

f1

+
+

Brief

+ + +
+
+
+

Synopsis

+
+Declared in <par-1.cpp>
+
+
+void
+f1();
+
+
+
+
+

Description

+

Custom par

+

Paragraph 1

+ +void f1(); + + + +
+
+
+
+

f2

+
+

Brief

+ + +
+
+
+

Synopsis

+
+Declared in <par-1.cpp>
+
+
+void
+f2();
+
+
+
+
+

Description

+

Custom par

+

Paragraph 2

+ +void f2(); + + + +
+
+
+
+

f3

+
+

Brief

+ + +
+
+
+

Synopsis

+
+Declared in <par-1.cpp>
+
+
+void
+f3();
+
+
+
+
+

Description

+

Custom par

+ +void f3(); + + + +
+
+
+
+

f4

+
+

Brief

+ + +
+
+
+

Synopsis

+
+Declared in <par-1.cpp>
+
+
+void
+f4();
+
+
+
+
+

Description

+

Custom par

+ +void f4(); + + + +
+
+ +
+
+

Created with MrDocs

+
+ + \ No newline at end of file diff --git a/test-files/golden-tests/javadoc/par-1.xml b/test-files/golden-tests/javadoc/par-1.xml new file mode 100644 index 0000000000..97801a74e8 --- /dev/null +++ b/test-files/golden-tests/javadoc/par-1.xml @@ -0,0 +1,60 @@ + + + + + + + + Brief + + Custom par + + Paragraph 1 + + + void f1(); + + + + + + + + Brief + + Custom par + + Paragraph 2 + + + void f2(); + + + + + + + + Brief + + Custom par + + void f3(); + + + + + + + + Brief + + Custom par + + void f4(); + + + + + diff --git a/test-files/golden-tests/snippets/is_prime.adoc b/test-files/golden-tests/snippets/is_prime.adoc index 23c1a44666..d1b871ada3 100644 --- a/test-files/golden-tests/snippets/is_prime.adoc +++ b/test-files/golden-tests/snippets/is_prime.adoc @@ -40,6 +40,9 @@ is_prime(unsigned long long n) noexcept; === Description + +=== Complexity + Linear in n. diff --git a/test-files/golden-tests/snippets/is_prime.html b/test-files/golden-tests/snippets/is_prime.html index 7b47fa30fb..91257d7381 100644 --- a/test-files/golden-tests/snippets/is_prime.html +++ b/test-files/golden-tests/snippets/is_prime.html @@ -46,6 +46,7 @@

Synopsis

Description

+

Complexity

Linear in n.

diff --git a/test-files/golden-tests/snippets/is_prime.xml b/test-files/golden-tests/snippets/is_prime.xml index cd4d30651e..fa1e5d1be3 100644 --- a/test-files/golden-tests/snippets/is_prime.xml +++ b/test-files/golden-tests/snippets/is_prime.xml @@ -14,6 +14,7 @@ Return true if a number is prime. + Complexity Linear in n.