diff options
author | Topi Reinio <[email protected]> | 2025-05-22 09:12:28 +0000 |
---|---|---|
committer | Topi Reinio <[email protected]> | 2025-06-04 10:53:17 +0000 |
commit | 76fac13efee68b58cd7604b804360aa18ba7d986 (patch) | |
tree | f5e070893848e35e2bf17638b92d59ac3a98ff62 /src/qdoc | |
parent | f7efd5d856656df7293629196b42fbef18ef9efd (diff) |
After parsing all documentation comments, QDoc traverses though the
node tree and recursively marks all undocumented nodes as 'internal'.
This process did not check whether an undocumented aggregate node
(class or QML type) has documented members. This lead to a situation
where forgetting to document a \class or a \qmltype lead QDoc to
silently ignore the documentation for the type's members.
Add this check, document the new warning in QDoc manual, and add a
simple test project that produces these warnings.
Fixes: QTBUG-135694
Change-Id: I34b77171e7a1fa3a1372aa93ad344885b2abb744
Reviewed-by: David Boddie <[email protected]>
Reviewed-by: Topi Reiniƶ <[email protected]>
Diffstat (limited to 'src/qdoc')
6 files changed, 103 insertions, 0 deletions
diff --git a/src/qdoc/qdoc/doc/qdoc-warnings.qdoc b/src/qdoc/qdoc/doc/qdoc-warnings.qdoc index 97b86daa6..ee9ec6744 100644 --- a/src/qdoc/qdoc/doc/qdoc-warnings.qdoc +++ b/src/qdoc/qdoc/doc/qdoc-warnings.qdoc @@ -137,6 +137,18 @@ fully qualified with the scope of the class that declares the function. + \section1 No output generated for <entity> because <parent> is undocumented + + QDoc issues this warning when parsing a documentation comment for an + API entity such as a class member, but cannot produce any output because + the associated parent (class) is not documented. Ensure that the parent is + documented and that QDoc is configured to parse the source file containing + the documentation comment. + + If the documented member belongs to a class that is not meant to be + documented, mark the class as \qdoccmd {internal} or use the + \qdoccmd {dontdocument} command. + \section1 QML type <TypeName> documented with <ClassName> as its native type. Replacing <ClassName> with <OtherClass> If the \qdoccmd nativetype command is used with the same argument in multiple QML type documentation comments that belong to the same diff --git a/src/qdoc/qdoc/src/qdoc/aggregate.cpp b/src/qdoc/qdoc/src/qdoc/aggregate.cpp index 0a1aa2606..2da529006 100644 --- a/src/qdoc/qdoc/src/qdoc/aggregate.cpp +++ b/src/qdoc/qdoc/src/qdoc/aggregate.cpp @@ -190,6 +190,47 @@ FunctionNode *Aggregate::findFunctionChild(const FunctionNode *clone) return func_it != (*funcs_it).end() ? *func_it : nullptr; } + +/*! + \internal + Warn about documented, non-private children under undocumented parents - unless + the \a child is explicitly set \internal, or their parent() does not match \a + aggregate, indicating that \a child is a related non-member. The latter + condition avoids duplicate warnings as the node appears under multiple + aggregates. + + The warning is skipped for children of proxy nodes and namespace nodes. Proxies + have no documentation as they're automatically generated. For namespaces, this + check is done separately after merging potentially multiple namespace nodes + referring to the same namespace; see + NamespaceNode::reportDocumentedChildrenInUndocumentedNamespace(). + + Likewise, the warning is skipped for children of aggregates marked with the + \\dontdocument command. + + If either \c {-no-linkerrors} or \c {-showinternal} command-line option is set, + these warnings are not generated. \c {-no-linkerrors} avoids false positives + in cases where the aggregate is documented outside the current project and was + not loaded from index. With \c {-showinternal} set, the warning is not required as + internal nodes generate output. +*/ +static void warnAboutDocumentedChildInUndocumentedParent(const Node *aggregate, const Node *child) +{ + Q_ASSERT(child); + const auto *parent{child->parent()}; + if (parent && parent == aggregate && !child->isPrivate() && child->status() != Node::Internal + && !parent->isProxyNode() && !parent->isNamespace() &&!parent->isDontDocument() + && !parent->hasDoc()) { + const auto &config{Config::instance()}; + if (!config.get(CONFIG_NOLINKERRORS).asBool() && !config.get(CONFIG_SHOWINTERNAL).asBool()) + child->doc().location().warning( + "No output generated for %1 '%2' because '%3' is undocumented"_L1 + .arg(child->nodeTypeString(), + child->plainFullName(), + child->parent()->name())); + } +} + /*! Mark all child nodes that have no documentation as having private access and internal status. qdoc will then ignore @@ -210,6 +251,8 @@ void Aggregate::markUndocumentedChildrenInternal() child->setAccess(Access::Private); child->setStatus(Node::Internal); } + } else { + warnAboutDocumentedChildInUndocumentedParent(this, child); } if (child->isAggregate()) { static_cast<Aggregate *>(child)->markUndocumentedChildrenInternal(); diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/expected/undocumented-class-with-documented-members.index b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/expected/undocumented-class-with-documented-members.index new file mode 100644 index 000000000..7fdf37dcb --- /dev/null +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/expected/undocumented-class-with-documented-members.index @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE QDOCINDEX> +<INDEX url="" title="Undocumented class with documented members Reference Documentation" version="" project="Undocumented class with documented members"> + <namespace name="" status="active" access="public" module="undocumented class with documented members"/> +</INDEX> diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/src/class.cpp b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/src/class.cpp new file mode 100644 index 000000000..c1baa79cd --- /dev/null +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/src/class.cpp @@ -0,0 +1,18 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +#include "class.h" + +/*! + A member function of a class that happens to be undocumented. + */ +void TestClass::method() {} + +/*! + \fn void globalFunc() + \relates TestClass +*/ + +/*! + \variable TestClass::i +*/ diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/src/class.h b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/src/class.h new file mode 100644 index 000000000..8c5dd17a4 --- /dev/null +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/src/class.h @@ -0,0 +1,15 @@ +// Copyright (C) 2025 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +#pragma once + +void globalFunc() {} + +class TestClass +{ +public: + TestClass() = default; + void method(); + + int i {0}; +}; diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/undocumented_class.qdocconf b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/undocumented_class.qdocconf new file mode 100644 index 000000000..f2aad47a1 --- /dev/null +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/undocumented_class/undocumented_class.qdocconf @@ -0,0 +1,10 @@ +project = Undocumented class with documented members +moduleheader = class.h +{includepaths,headerdirs,sourcedirs} = src + +locationinfo = false + +# This project generates three warnings but no .html output +# TODO: Test the actual content of warnings +warninglimit = 3 +warninglimit.enabled = true |