summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTopi Reinio <topi.reinio@qt.io>2020-02-01 20:49:06 +0100
committerTopi Reinio <topi.reinio@qt.io>2020-02-04 09:13:52 +0100
commit7767b21452e9f46408086d0ee6d7cc7be702b864 (patch)
treed96526e06ffb24a7dc6cad7788bee192983c99b6
parent4dd7c301fff2821bac6c03ea56ee27bc3eeaeaed (diff)
qdoc: Correctly resolve qualified path of external base classes
Often, a documented class inherits from a base that lives in another documentation module. QDoc recorded only the class name of such bases, omitting any qualified path. Fix this issue in the Clang-parser. Add an autotest for verifying documentation with cross-module inheritance and links. This requires adding a mechanism for copying the generated .index file(s) into a location where QDoc searches index files in. Fixes: QTBUG-81793 Change-Id: I4019a1ca3a0e4c69bccc1a92740fd51907bfb24d Reviewed-by: Paul Wicking <paul.wicking@qt.io>
-rw-r--r--src/qdoc/clangcodeparser.cpp5
-rw-r--r--tests/auto/qdoc/generatedoutput/crossmodule/CrossModule2
-rw-r--r--tests/auto/qdoc/generatedoutput/crossmodule/crossmodule.qdocconf10
-rw-r--r--tests/auto/qdoc/generatedoutput/crossmodule/testtype.cpp56
-rw-r--r--tests/auto/qdoc/generatedoutput/crossmodule/testtype.h37
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html23
-rw-r--r--tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype.html57
-rw-r--r--tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp28
8 files changed, 216 insertions, 2 deletions
diff --git a/src/qdoc/clangcodeparser.cpp b/src/qdoc/clangcodeparser.cpp
index ed5272b8a..169cfc568 100644
--- a/src/qdoc/clangcodeparser.cpp
+++ b/src/qdoc/clangcodeparser.cpp
@@ -689,8 +689,9 @@ CXChildVisitResult ClangVisitor::visitHeader(CXCursor cursor, CXSourceLocation l
auto baseNode = findNodeForCursor(qdb_, baseCursor);
auto classe = static_cast<ClassNode *>(parent_);
if (baseNode == nullptr || !baseNode->isClassNode()) {
- QString bcName = fromCXString(clang_getCursorSpelling(baseCursor));
- classe->addUnresolvedBaseClass(access, QStringList(bcName), bcName);
+ QString bcName = reconstructQualifiedPathForCursor(baseCursor);
+ classe->addUnresolvedBaseClass(access,
+ bcName.split(QLatin1String("::"), QString::SkipEmptyParts), bcName);
return CXChildVisit_Continue;
}
auto baseClasse = static_cast<ClassNode *>(baseNode);
diff --git a/tests/auto/qdoc/generatedoutput/crossmodule/CrossModule b/tests/auto/qdoc/generatedoutput/crossmodule/CrossModule
new file mode 100644
index 000000000..df9c82ad5
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/crossmodule/CrossModule
@@ -0,0 +1,2 @@
+#include "../TestCPP"
+#include "testtype.h"
diff --git a/tests/auto/qdoc/generatedoutput/crossmodule/crossmodule.qdocconf b/tests/auto/qdoc/generatedoutput/crossmodule/crossmodule.qdocconf
new file mode 100644
index 000000000..fb4a6be77
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/crossmodule/crossmodule.qdocconf
@@ -0,0 +1,10 @@
+project = CrossModule
+includepaths += -I.
+
+depends = testcpp
+
+headers = testtype.h
+sources = testtype.cpp
+
+HTML.nosubdirs = true
+HTML.outputsubdir = crossmodule
diff --git a/tests/auto/qdoc/generatedoutput/crossmodule/testtype.cpp b/tests/auto/qdoc/generatedoutput/crossmodule/testtype.cpp
new file mode 100644
index 000000000..50d5d4845
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/crossmodule/testtype.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "testtype.h"
+
+/*!
+ \module CrossModule
+*/
+/*!
+ \class TestType
+ \inmodule CrossModule
+ \brief A class inheriting another class that lives in an external doc
+ module.
+
+ \section1 Linking
+
+ These links go to the parent class:
+ \list
+ \li \l {TestQDoc::TestDerived}
+ \li \l {TestQDoc::}{Test} class \l Usage.
+ \li QDOCTEST_MACRO
+ \endlist
+
+ \sa {TestQDoc::Test::}{someFunction()}
+*/
+
+/*!
+ Nothing to see here.
+*/
+void TestType::nothing()
+{
+}
diff --git a/tests/auto/qdoc/generatedoutput/crossmodule/testtype.h b/tests/auto/qdoc/generatedoutput/crossmodule/testtype.h
new file mode 100644
index 000000000..957505fcc
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/crossmodule/testtype.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#pragma once
+
+#include "../testcpp.h"
+
+class TestType : public TestQDoc::TestDerived
+{
+public:
+ TestType() {}
+ void nothing() {}
+};
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html b/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html
new file mode 100644
index 000000000..21870bb3f
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype-members.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testtype.cpp -->
+ <title>List of All Members for TestType | CrossModule</title>
+</head>
+<body>
+<li>TestType</li>
+<div class="sidebar"><div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">List of All Members for TestType</h1>
+<p>This is the complete list of members for <a href="testtype.html">TestType</a>, including inherited members.</p>
+<ul>
+<li class="fn"><span class="name"><b><a href="testqdoc-test.html#inlineFunction">inlineFunction</a></b></span>()</li>
+<li class="fn"><span class="name"><b><a href="testtype.html#nothing">nothing</a></b></span>()</li>
+<li class="fn"><span class="name"><b><a href="testqdoc-test.html#overload">overload</a></b></span>()</li>
+<li class="fn"><span class="name"><b><a href="testqdoc-test.html#overload-1">overload</a></b></span>(bool )</li>
+<li class="fn"><span class="name"><b><a href="testqdoc-test.html#someFunction">someFunction</a></b></span>(int ) : int</li>
+<li class="fn"><span class="name"><b><a href="testqdoc-test.html#someFunctionDefaultArg">someFunctionDefaultArg</a></b></span>(int , bool )</li>
+<li class="fn"><span class="name"><b><a href="testqdoc-testderived.html#virtualFun">virtualFun</a></b></span>()</li>
+</ul>
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype.html b/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype.html
new file mode 100644
index 000000000..dcf2114b7
--- /dev/null
+++ b/tests/auto/qdoc/generatedoutput/expected_output/crossmodule/testtype.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8">
+<!-- testtype.cpp -->
+ <title>TestType Class | CrossModule</title>
+</head>
+<body>
+<li>TestType</li>
+<div class="sidebar">
+<div class="toc">
+<h3><a name="toc">Contents</a></h3>
+<ul>
+<li class="level1"><a href="#public-functions">Public Functions</a></li>
+<li class="level1"><a href="#details">Detailed Description</a></li>
+<li class="level2"><a href="#linking">Linking</a></li>
+</ul>
+</div>
+<div class="sidebar-content" id="sidebar-content"></div></div>
+<h1 class="title">TestType Class</h1>
+<!-- $$$TestType-brief -->
+<p>A class inheriting another class that lives in an external doc module. <a href="#details">More...</a></p>
+<!-- @@@TestType -->
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> Header:</td><td class="memItemRight bottomAlign"> <span class="preprocessor">#include &lt;TestType&gt;</span>
+</td></tr><tr><td class="memItemLeft rightAlign topAlign"> Inherits:</td><td class="memItemRight bottomAlign"> <a href="testqdoc-testderived.html">TestQDoc::TestDerived</a></td></tr></table></div><ul>
+<li><a href="testtype-members.html">List of all members, including inherited members</a></li>
+</ul>
+<a name="public-functions"></a>
+<h2 id="public-functions">Public Functions</h2>
+<div class="table"><table class="alignedsummary">
+<tr><td class="memItemLeft rightAlign topAlign"> void </td><td class="memItemRight bottomAlign"><b><a href="testtype.html#nothing">nothing</a></b>()</td></tr>
+</table></div>
+<a name="details"></a>
+<!-- $$$TestType-description -->
+<div class="descr">
+<h2 id="details">Detailed Description</h2>
+<a name="linking"></a>
+<h3 id="linking">Linking</h3>
+<p>These links go to the parent class:</p>
+<ul>
+<li><a href="testqdoc-testderived.html">TestQDoc::TestDerived</a></li>
+<li><a href="testqdoc-test.html">Test</a> class <a href="testqdoc.html#usage">Usage</a>.</li>
+<li><a href="testqdoc.html#QDOCTEST_MACRO">QDOCTEST_MACRO</a></li>
+</ul>
+</div>
+<p><b>See also </b><a href="testqdoc-test.html#someFunction">someFunction</a>().</p>
+<!-- @@@TestType -->
+<div class="func">
+<h2>Member Function Documentation</h2>
+<!-- $$$nothing[overload1]$$$nothing -->
+<h3 class="fn" id="nothing"><a name="nothing"></a><span class="type">void</span> TestType::<span class="name">nothing</span>()</h3>
+<p>Nothing to see here.</p>
+<!-- @@@nothing -->
+</div>
+</body>
+</html>
diff --git a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
index 3237bde26..f1c0b892e 100644
--- a/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
+++ b/tests/auto/qdoc/generatedoutput/tst_generatedoutput.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include <QProcess>
#include <QTemporaryDir>
+#include <QDirIterator>
#include <QtTest>
class tst_generatedOutput : public QObject
@@ -61,6 +62,7 @@ private slots:
void scopedEnum();
void dontDocument();
void inheritedQmlPropertyGroups();
+ void crossModuleLinking();
private:
QScopedPointer<QTemporaryDir> m_outputDir;
@@ -70,6 +72,7 @@ private:
void compareLineByLine(const QStringList &expectedFiles);
void testAndCompare(const char *input, const char *outNames, const char *extraParams = nullptr,
const char *outputPathPrefix = nullptr);
+ void copyIndexFiles();
};
void tst_generatedOutput::initTestCase()
@@ -162,6 +165,20 @@ void tst_generatedOutput::testAndCompare(const char *input, const char *outNames
compareLineByLine(expectedOuts);
}
+// Copy <project>.index to <project>/<project>.index in the outputdir
+void tst_generatedOutput::copyIndexFiles()
+{
+ QDirIterator it(m_outputDir->path(), QStringList("*.index"), QDir::Files, QDirIterator::Subdirectories);
+ while (it.hasNext()) {
+ QFileInfo fileInfo(it.next());
+ QDir indexDir(m_outputDir->path());
+ QVERIFY(indexDir.mkpath(fileInfo.baseName()));
+ QVERIFY(indexDir.cd(fileInfo.baseName()));
+ if (!indexDir.exists(fileInfo.fileName()))
+ QVERIFY(QFile::copy(fileInfo.filePath(), indexDir.filePath(fileInfo.fileName())));
+ }
+}
+
void tst_generatedOutput::htmlFromQDocFile()
{
testAndCompare("test.qdocconf",
@@ -306,6 +323,17 @@ void tst_generatedOutput::inheritedQmlPropertyGroups()
"qmlpropertygroups/qml-qdoc-test-anotherchild-members.html");
}
+void tst_generatedOutput::crossModuleLinking()
+{
+ htmlFromCpp();
+ copyIndexFiles();
+ QString indexDir = QLatin1String("-indexdir ") + m_outputDir->path();
+ testAndCompare("crossmodule/crossmodule.qdocconf",
+ "crossmodule/testtype.html "
+ "crossmodule/testtype-members.html",
+ indexDir.toLatin1().data());
+}
+
QTEST_APPLESS_MAIN(tst_generatedOutput)
#include "tst_generatedoutput.moc"