diff options
5 files changed, 53 insertions, 18 deletions
diff --git a/src/qdoc/sections.cpp b/src/qdoc/sections.cpp index 21b05ba6d..6f158084f 100644 --- a/src/qdoc/sections.cpp +++ b/src/qdoc/sections.cpp @@ -142,7 +142,6 @@ void Section::clear() { qDeleteAll(m_classMapList); qDeleteAll(m_classNodesList); - m_memberMap.clear(); m_obsoleteMemberMap.clear(); m_reimplementedMemberMap.clear(); m_classMapList.clear(); @@ -246,7 +245,7 @@ void Section::insert(Node *node) m_obsoleteMemberMap.insert(key, node); } else { if (!inherited || m_style == AllMembers) - m_memberMap.insert(key, node); + m_members.push_back(node); if (inherited && (node->parent()->isClassNode() || node->parent()->isNamespace())) { if (m_inheritedMembers.isEmpty() @@ -305,7 +304,7 @@ ClassMap *Section::newClassMap(const Aggregate *aggregate) void Section::add(ClassMap *classMap, Node *n) { const QString key = sortName(n); - m_memberMap.insert(key, n); + m_members.push_back(n); classMap->second.insert(key, n); } @@ -315,16 +314,54 @@ void Section::add(ClassMap *classMap, Node *n) */ void Section::reduce() { - if (!isEmpty()) { - m_members = m_memberMap.values().toVector(); - m_reimplementedMembers = m_reimplementedMemberMap.values().toVector(); - for (const auto &cm : m_classMapList) { - auto *ckn = new ClassNodes; - ckn->first = cm->first; - ckn->second = cm->second.values().toVector(); - m_classNodesList.append(ckn); - } + // TODO:TEMPORARY:INTERMEDITATE: Section uses a series of maps + // to internally manage the categorization of the various members + // of an aggregate. It further uses a secondary "flattened" + // (usually vector) version that is later used by consumers of a + // Section content. + // + // One of the uses of those maps is that of ordering, by using + // keys generated with `sortName`. + // Nonetheless, this is the only usage that comes from the keys, + // as they are neither necessary nor used outside of the internal + // code for Section. + // + // Hence, the codebase is moving towards removing the maps in + // favor of building a flattened, consumer ready, version of the + // categorization directly, cutting the intermediate conversion + // step. + // + // To do so while keeping as much of the old behavior as possible, + // we provide a sorting for the flattened version that is based on + // `sortName`, as the previous ordering was. + // + // This acts as a relatively heavy pessimization, as `sortName`, + // used as a comparator, can be called multiple times for each + // Node, while before it would have been called almost-once. + // + // Instead of fixing this issue, by for example caching the + // sortName of each Node instance, we temporarily keep the + // pessimization while the various maps are removed. + // + // When all the maps are removed, we can remove `sortName`, which + // produces strings to use as key requiring a few allocations and + // expensive operations, with an actual comparator function, which + // should be more lightweight and more than offset the + // multiple-calls. + static auto node_less_than = [](const Node* left, const Node* right) { + return sortName(left) < sortName(right); + }; + + std::stable_sort(m_members.begin(), m_members.end(), node_less_than); + + m_reimplementedMembers = m_reimplementedMemberMap.values().toVector(); + for (const auto &cm : m_classMapList) { + auto *ckn = new ClassNodes; + ckn->first = cm->first; + ckn->second = cm->second.values().toVector(); + m_classNodesList.append(ckn); } + if (!m_obsoleteMemberMap.isEmpty()) { m_obsoleteMembers = m_obsoleteMemberMap.values().toVector(); } diff --git a/src/qdoc/sections.h b/src/qdoc/sections.h index b408891c9..f1b58ece6 100644 --- a/src/qdoc/sections.h +++ b/src/qdoc/sections.h @@ -34,7 +34,6 @@ public: ~Section(); void insert(Node *node); - void insert(const QString &key, Node *node) { m_memberMap.insert(key, node); } bool insertReimplementedMember(Node *node); ClassMap *newClassMap(const Aggregate *aggregate); @@ -45,7 +44,7 @@ public: void reduce(); [[nodiscard]] bool isEmpty() const { - return (m_memberMap.isEmpty() && m_inheritedMembers.isEmpty() + return (m_members.isEmpty() && m_inheritedMembers.isEmpty() && m_reimplementedMemberMap.isEmpty() && m_classMapList.isEmpty()); } @@ -82,7 +81,6 @@ private: QList<std::pair<Aggregate *, int>> m_inheritedMembers {}; ClassNodesList m_classNodesList {}; - QMultiMap<QString, Node *> m_memberMap {}; QMultiMap<QString, Node *> m_obsoleteMemberMap {}; QMultiMap<QString, Node *> m_reimplementedMemberMap {}; ClassMapList m_classMapList {}; diff --git a/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html b/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html index 1bfd9fef5..974819e53 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html +++ b/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html @@ -23,8 +23,8 @@ <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#overload-1" translate="no">overload</a></b></span>(bool)</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#someFunction" translate="no">someFunction</a></b></span>(int, int) : int</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#someFunctionDefaultArg" translate="no">someFunctionDefaultArg</a></b></span>(int, bool)</li> -<li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#virtualFun" translate="no">virtualFun</a></b></span>()</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-testderived.html#virtualFun" translate="no">virtualFun</a></b></span>()</li> +<li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#virtualFun" translate="no">virtualFun</a></b></span>()</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#operator-eq" translate="no">operator=</a></b></span>(TestQDoc::Test &&) : TestQDoc::Test &</li> </ul> </body> diff --git a/tests/auto/qdoc/generatedoutput/expected_output/properties/testqdoc-testderived-members.html b/tests/auto/qdoc/generatedoutput/expected_output/properties/testqdoc-testderived-members.html index c1bc22f3d..4d3461360 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/properties/testqdoc-testderived-members.html +++ b/tests/auto/qdoc/generatedoutput/expected_output/properties/testqdoc-testderived-members.html @@ -38,8 +38,8 @@ <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#someFunction" translate="no">someFunction</a></b></span>(int, int) : int</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#someFunctionDefaultArg" translate="no">someFunctionDefaultArg</a></b></span>(int, bool)</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-testderived.html#someProp-prop" translate="no">someProp</a></b></span>() : const QString &</li> -<li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#virtualFun" translate="no">virtualFun</a></b></span>()</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-testderived.html#virtualFun" translate="no">virtualFun</a></b></span>()</li> +<li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#virtualFun" translate="no">virtualFun</a></b></span>()</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#operator-eq" translate="no">operator=</a></b></span>(TestQDoc::Test &&) : TestQDoc::Test &</li> </ul> </td></tr> diff --git a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-testderived-members.html b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-testderived-members.html index 2873c37be..21fdd803d 100644 --- a/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-testderived-members.html +++ b/tests/auto/qdoc/generatedoutput/expected_output/testqdoc-testderived-members.html @@ -23,8 +23,8 @@ <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#overload-1" translate="no">overload</a></b></span>(bool)</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#someFunction" translate="no">someFunction</a></b></span>(int, int) : int</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#someFunctionDefaultArg" translate="no">someFunctionDefaultArg</a></b></span>(int, bool)</li> -<li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#virtualFun" translate="no">virtualFun</a></b></span>()</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-testderived.html#virtualFun" translate="no">virtualFun</a></b></span>()</li> +<li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#virtualFun" translate="no">virtualFun</a></b></span>()</li> <li class="fn" translate="no"><span class="name"><b><a href="testqdoc-test.html#operator-eq" translate="no">operator=</a></b></span>(TestQDoc::Test &&) : TestQDoc::Test &</li> </ul> </body> |