diff options
author | Paul Wicking <[email protected]> | 2025-08-15 23:59:17 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <[email protected]> | 2025-08-17 17:03:30 +0000 |
commit | 61e033dcc6da1ab8197b0ab3935e34d32fd6e285 (patch) | |
tree | a3f48d5a89fd58df75eec1bd4138df271b2f9826 | |
parent | c4f90317695c10019b8c62bd96ded9170bb409d3 (diff) |
QDoc: Fix QML type disambiguation in compact lists6.10
QDoc currently uses flawed logic to detect duplicate type names in
compact lists. The existing implementation only checks if the next
item in the same alphabetical paragraph has the same name, missing
many cases where duplicates appear elsewhere in the list. When
duplicates are detected, the disambiguation uses the project name
rather than the actual QML module name, making it unhelpful.
This creates confusion in multi-module documentation builds where
different QML modules contain types with the same name. Users cannot
distinguish between "Item" from QtQuick versus "Item" from a custom
module, as both appear identically in type listings.
This change implements comprehensive duplicate detection across the
entire list and uses the correct QML module name for disambiguation.
QML types with conflicting names now display as "TypeName: ModuleName"
only when actual conflicts exist, providing clear identification while
avoiding unnecessary clutter for unique names.
Fixes: QTBUG-138547
Change-Id: I1974b15dc10d6ff60477abc1beff1eaa552e5371
Reviewed-by: Topi Reiniƶ <[email protected]>
(cherry picked from commit 2547932075ab888c53a4bb9fa7d7fe1d317c3891)
Reviewed-by: Qt Cherry-pick Bot <[email protected]>
11 files changed, 77 insertions, 26 deletions
diff --git a/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp b/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp index 862e175f3..bae643aa3 100644 --- a/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp +++ b/src/qdoc/qdoc/src/qdoc/docbookgenerator.cpp @@ -1525,11 +1525,17 @@ void DocBookGenerator::generateCompactList(const Node *relative, const NodeMulti newLine(); } + // Build a map of all duplicate names across the entire list + QHash<QString, int> nameOccurrences; + for (const auto &[key, node] : nmm.asKeyValueRange()) { + QStringList pieces{node->fullName(relative).split("::"_L1)}; + const QString &name{pieces.last()}; + nameOccurrences[name]++; + } + // Actual output. int curParNr = 0; int curParOffset = 0; - QString previousName; - bool multipleOccurrences = false; m_writer->writeStartElement(dbNamespace, "variablelist"); m_writer->writeAttribute("role", selector); @@ -1588,16 +1594,13 @@ void DocBookGenerator::generateCompactList(const Node *relative, const NodeMulti // (more than one piece). QStringList pieces{it.value()->fullName(relative).split("::"_L1)}; const auto &name{pieces.last()}; - next = it; - ++next; - if (name != previousName) - multipleOccurrences = false; - if ((next != paragraph[curParNr].end()) && (name == next.value()->name())) { - multipleOccurrences = true; - previousName = name; + + // Add module disambiguation if there are multiple types with the same name + if (nameOccurrences[name] > 1) { + const QString moduleName = it.value()->isQmlNode() ? it.value()->logicalModuleName() + : it.value()->tree()->camelCaseModuleName(); + pieces.last().append(": %1"_L1.arg(moduleName)); } - if (multipleOccurrences && pieces.size() == 1) - pieces.last().append(": "_L1.arg(it.value()->tree()->camelCaseModuleName())); // Write the link to the element, which is identical if the element is obsolete or not. m_writer->writeStartElement(dbNamespace, "link"); diff --git a/src/qdoc/qdoc/src/qdoc/htmlgenerator.cpp b/src/qdoc/qdoc/src/qdoc/htmlgenerator.cpp index bbe07a167..5b6e0b0dc 100644 --- a/src/qdoc/qdoc/src/qdoc/htmlgenerator.cpp +++ b/src/qdoc/qdoc/src/qdoc/htmlgenerator.cpp @@ -2722,10 +2722,16 @@ void HtmlGenerator::generateCompactList(ListType listType, const Node *relative, out() << "<div class=\"flowListDiv\" translate=\"no\">\n"; m_numTableRows = 0; + // Build a map of all duplicate names across the entire list + QHash<QString, int> nameOccurrences; + for (const auto &[key, node] : nmm.asKeyValueRange()) { + QStringList pieces{node->fullName(relative).split("::"_L1)}; + const QString &name{pieces.last()}; + nameOccurrences[name]++; + } + int curParNr = 0; int curParOffset = 0; - QString previousName; - bool multipleOccurrences = false; for (int i = 0; i < nmm.size(); i++) { while ((curParNr < NumParagraphs) && (curParOffset == paragraph[curParNr].size())) { @@ -2777,16 +2783,13 @@ void HtmlGenerator::generateCompactList(ListType listType, const Node *relative, QStringList pieces{it.value()->fullName(relative).split("::"_L1)}; const auto &name{pieces.last()}; - next = it; - ++next; - if (name != previousName) - multipleOccurrences = false; - if ((next != paragraph[curParNr].end()) && (name == next.value()->name())) { - multipleOccurrences = true; - previousName = name; + + // Add module disambiguation if there are multiple types with the same name + if (nameOccurrences[name] > 1) { + const QString moduleName = it.value()->isQmlNode() ? it.value()->logicalModuleName() + : it.value()->tree()->camelCaseModuleName(); + pieces.last().append(": %1"_L1.arg(moduleName)); } - if (multipleOccurrences && pieces.size() == 1) - pieces.last().append(": %1"_L1.arg(it.value()->tree()->camelCaseModuleName())); out() << protectEnc(pieces.last()); out() << "</a>"; diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/barmod-qmlmodule.html b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/barmod-qmlmodule.html index 877151901..e687f346f 100644 --- a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/barmod-qmlmodule.html +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/barmod-qmlmodule.html @@ -12,7 +12,7 @@ </div> <!-- @@@BarMod --> <div class="table"><table class="annotated"> -<tr class="odd topAlign"><td class="tblName" translate="no"><p><a href="qml-barmod-foo.html">Foo</a></p></td></tr> +<tr class="odd topAlign"><td class="tblName" translate="no"><p><a href="qml-barmod-foo.html">Foo</a></p></td><td class="tblDescr"><p>A Foo type in BarMod</p></td></tr> </table></div> </body> </html> diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/clashingqmltypes.index b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/clashingqmltypes.index index 2edd1df14..e82b8c5b1 100644 --- a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/clashingqmltypes.index +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/clashingqmltypes.index @@ -2,8 +2,9 @@ <!DOCTYPE QDOCINDEX> <INDEX url="" title="ClashingQmlTypes Reference Documentation" version="" project="ClashingQmlTypes"> <namespace name="" status="active" access="public" module="clashingqmltypes"> - <qmlclass name="Foo" qml-module-name="BarMod" fullname="BarMod.Foo" href="qml-barmod-foo.html" status="active" access="public" location="test.qdoc" documented="true" title="Foo" fulltitle="Foo" subtitle=""/> - <qmlclass name="Foo" qml-module-name="FooMod" fullname="FooMod.Foo" href="qml-foomod-foo.html" status="active" access="public" location="test.qdoc" documented="true" title="Foo" fulltitle="Foo" subtitle=""/> + <qmlclass name="Foo" qml-module-name="BarMod" fullname="BarMod.Foo" href="qml-barmod-foo.html" status="active" access="public" location="test.qdoc" documented="true" title="Foo" fulltitle="Foo" subtitle="" brief="A Foo type in BarMod"/> + <qmlclass name="Foo" qml-module-name="FooMod" fullname="FooMod.Foo" href="qml-foomod-foo.html" status="active" access="public" location="test.qdoc" documented="true" title="Foo" fulltitle="Foo" subtitle="" brief="A Foo type in FooMod"/> + <page name="qmltypes-overview.html" href="qmltypes-overview.html" status="active" location="test.qdoc" documented="true" subtype="page" title="QML Types Overview" fulltitle="QML Types Overview" subtitle=""/> <qmlmodule name="BarMod" qml-module-name="BarMod" href="barmod-qmlmodule.html" status="active" location="test.qdoc" documented="true" seen="true" title=""/> <qmlmodule name="FooMod" qml-module-name="FooMod" href="foomod-qmlmodule.html" status="active" location="test.qdoc" documented="true" seen="true" title=""/> </namespace> diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/foomod-qmlmodule.html b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/foomod-qmlmodule.html index 4c779d1ed..361077442 100644 --- a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/foomod-qmlmodule.html +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/foomod-qmlmodule.html @@ -12,7 +12,7 @@ </div> <!-- @@@FooMod --> <div class="table"><table class="annotated"> -<tr class="odd topAlign"><td class="tblName" translate="no"><p><a href="qml-foomod-foo.html">Foo</a></p></td></tr> +<tr class="odd topAlign"><td class="tblName" translate="no"><p><a href="qml-foomod-foo.html">Foo</a></p></td><td class="tblDescr"><p>A Foo type in FooMod</p></td></tr> </table></div> </body> </html> diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-barmod-foo-members.html b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-barmod-foo-members.html index e2633203e..d732327b1 100644 --- a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-barmod-foo-members.html +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-barmod-foo-members.html @@ -3,6 +3,7 @@ <head> <meta charset="utf-8"> <!-- test.qdoc --> + <meta name="description" content="A Foo type in BarMod."> <title>List of All Members for Foo | ClashingQmlTypes</title> </head> <body> diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-barmod-foo.html b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-barmod-foo.html index d20348ede..5a09a027e 100644 --- a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-barmod-foo.html +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-barmod-foo.html @@ -3,6 +3,7 @@ <head> <meta charset="utf-8"> <!-- test.qdoc --> + <meta name="description" content="A Foo type in BarMod."> <title>Foo QML Type | ClashingQmlTypes</title> </head> <body> @@ -16,6 +17,9 @@ </div> <div class="sidebar-content" id="sidebar-content"></div></div> <h1 class="title" translate="no">Foo QML Type</h1> +<!-- $$$Foo-brief --> +<p>A Foo type in <a href="barmod-qmlmodule.html" translate="no">BarMod</a>. <a href="#details">More...</a></p> +<!-- @@@Foo --> <div class="table"><table class="alignedsummary requisites" translate="no"> <tr><td class="memItemLeft rightAlign topAlign"> Import Statement:</td><td class="memItemRight bottomAlign"> <code translate="no">import BarMod</code></td></tr> </table></div> diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-foomod-foo-members.html b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-foomod-foo-members.html index bb330375b..2d140acb7 100644 --- a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-foomod-foo-members.html +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-foomod-foo-members.html @@ -3,6 +3,7 @@ <head> <meta charset="utf-8"> <!-- test.qdoc --> + <meta name="description" content="A Foo type in FooMod."> <title>List of All Members for Foo | ClashingQmlTypes</title> </head> <body> diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-foomod-foo.html b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-foomod-foo.html index 7ed5650d0..6ff4b3fce 100644 --- a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-foomod-foo.html +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qml-foomod-foo.html @@ -3,6 +3,7 @@ <head> <meta charset="utf-8"> <!-- test.qdoc --> + <meta name="description" content="A Foo type in FooMod."> <title>Foo QML Type | ClashingQmlTypes</title> </head> <body> @@ -16,6 +17,9 @@ </div> <div class="sidebar-content" id="sidebar-content"></div></div> <h1 class="title" translate="no">Foo QML Type</h1> +<!-- $$$Foo-brief --> +<p>A Foo type in <a href="foomod-qmlmodule.html" translate="no">FooMod</a>. <a href="#details">More...</a></p> +<!-- @@@Foo --> <div class="table"><table class="alignedsummary requisites" translate="no"> <tr><td class="memItemLeft rightAlign topAlign"> Import Statement:</td><td class="memItemRight bottomAlign"> <code translate="no">import FooMod</code></td></tr> </table></div> diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qmltypes-overview.html b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qmltypes-overview.html new file mode 100644 index 000000000..0736dd204 --- /dev/null +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/expected/html/qmltypes-overview.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> +<!-- test.qdoc --> + <title>QML Types Overview | ClashingQmlTypes</title> +</head> +<body> +<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div> +<h1 class="title">QML Types Overview</h1> +<!-- $$$qmltypes-overview.html-description --> +<div class="descr" id="details"> +<p>This page lists all QML types to demonstrate disambiguation.</p> +<p class="centerAlign functionIndex" translate="no"><b><a href="#f">F</a> </b></p> +<div class="flowListDiv" translate="no"> +<dl class="flowList odd"><dt class="alphaChar" id="f"><b>F</b></dt> +<dd><a href="qml-foomod-foo.html">Foo: FooMod</a></dd> +<dd><a href="qml-barmod-foo.html">Foo: BarMod</a></dd> +</dl> +</div> +</div> +<!-- @@@qmltypes-overview.html --> +</body> +</html> diff --git a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/src/test.qdoc b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/src/test.qdoc index c03d21486..05b38fdf9 100644 --- a/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/src/test.qdoc +++ b/src/qdoc/qdoc/tests/validateqdocoutputfiles/testdata/clashing_qmltypes/src/test.qdoc @@ -6,8 +6,18 @@ /*! \qmltype Foo \inqmlmodule FooMod + \brief A Foo type in FooMod. */ /*! \qmltype Foo \inqmlmodule BarMod + \brief A Foo type in BarMod. + */ + +/*! \page qmltypes-overview.html + \title QML Types Overview + + This page lists all QML types to demonstrate disambiguation. + + \generatelist qmltypes */ |