summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/clangcodemodel/clangdclient.cpp12
-rw-r--r--src/plugins/clangcodemodel/test/clangdtests.cpp23
-rw-r--r--src/plugins/coreplugin/editormanager/editormanager.h4
-rw-r--r--src/plugins/cppeditor/CMakeLists.txt2
-rw-r--r--src/plugins/cppeditor/cppeditor.qbs1
-rw-r--r--src/plugins/cppeditor/cppeditor_dependencies.pri1
-rw-r--r--src/plugins/cppeditor/cppeditorplugin.h10
-rw-r--r--src/plugins/cppeditor/cppeditortestcase.cpp13
-rw-r--r--src/plugins/cppeditor/cppeditortestcase.h5
-rw-r--r--src/plugins/cppeditor/cppquickfix_test.cpp4
-rw-r--r--src/plugins/cppeditor/cppuseselections_test.cpp13
-rw-r--r--src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp121
-rw-r--r--src/plugins/cpptools/cpptoolstestcase.cpp11
-rw-r--r--src/plugins/cpptools/cpptoolstestcase.h19
-rw-r--r--src/plugins/projectexplorer/project.h4
-rw-r--r--src/plugins/texteditor/texteditor.cpp4
16 files changed, 207 insertions, 40 deletions
diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp
index b168045395..d1ec86393e 100644
--- a/src/plugins/clangcodemodel/clangdclient.cpp
+++ b/src/plugins/clangcodemodel/clangdclient.cpp
@@ -36,6 +36,7 @@
#include <cpptools/cppvirtualfunctionassistprovider.h>
#include <cpptools/cppvirtualfunctionproposalitem.h>
#include <languageclient/languageclientinterface.h>
+#include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h>
#include <projectexplorer/session.h>
#include <texteditor/basefilefind.h>
@@ -513,11 +514,14 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
setLocatorsEnabled(false);
setProgressTitleForToken(indexingToken(), tr("Parsing C/C++ Files (clangd)"));
setCurrentProject(project);
- connect(this, &Client::workDone, this, [this](const ProgressToken &token) {
+ connect(this, &Client::workDone, this, [this, project](const ProgressToken &token) {
const QString * const val = Utils::get_if<QString>(&token);
if (val && *val == indexingToken()) {
d->isFullyIndexed = true;
emit indexingFinished();
+#ifdef WITH_TESTS
+ emit project->indexingFinished("Indexer.Clangd");
+#endif
}
});
@@ -848,6 +852,8 @@ void ClangdClient::followSymbol(
return;
}
+ qCDebug(clangdLog) << "follow symbol requested" << document->filePath()
+ << cursor.blockNumber() << cursor.positionInBlock();
d->followSymbolData.emplace(this, ++d->nextFollowSymbolId, cursor, editorWidget,
DocumentUri::fromFilePath(document->filePath()),
std::move(callback), openInSplit);
@@ -856,6 +862,7 @@ void ClangdClient::followSymbol(
// AST node corresponding to the cursor position, so we can find out whether
// we have to look for overrides.
const auto gotoDefCallback = [this, id = d->followSymbolData->id](const Utils::Link &link) {
+ qCDebug(clangdLog) << "received go to definition response";
if (!link.hasValidTarget()) {
d->followSymbolData.reset();
return;
@@ -872,6 +879,7 @@ void ClangdClient::followSymbol(
Range(cursor)));
astRequest.setResponseCallback([this, id = d->followSymbolData->id](
const AstRequest::Response &response) {
+ qCDebug(clangdLog) << "received ast response";
if (!d->followSymbolData || d->followSymbolData->id != id)
return;
const auto result = response.result();
@@ -891,6 +899,8 @@ void ClangdClient::Private::handleGotoDefinitionResult()
QTC_ASSERT(followSymbolData->defLink.hasValidTarget(), return);
QTC_ASSERT(followSymbolData->cursorNode.isValid(), return);
+ qCDebug(clangdLog) << "handling go to definition result";
+
// No dis-ambiguation necessary. Call back with the link and finish.
if (!followSymbolData->cursorNode.isMemberFunctionCall()
&& !followSymbolData->cursorNode.isPureVirtualDeclaration()) {
diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp
index 4c109c888a..d0b0cf97bc 100644
--- a/src/plugins/clangcodemodel/test/clangdtests.cpp
+++ b/src/plugins/clangcodemodel/test/clangdtests.cpp
@@ -49,6 +49,7 @@
using namespace CPlusPlus;
using namespace Core;
+using namespace CppTools::Tests;
using namespace ProjectExplorer;
namespace ClangCodeModel {
@@ -67,20 +68,6 @@ void ClangdTests::initTestCase()
settings->setUseClangd(true);
}
-template <typename Signal> static bool waitForSignalOrTimeout(
- const typename QtPrivate::FunctionPointer<Signal>::Object *sender, Signal signal)
-{
- QTimer timer;
- timer.setSingleShot(true);
- timer.setInterval(timeOutInMs());
- QEventLoop loop;
- QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
- QObject::connect(sender, signal, &loop, &QEventLoop::quit);
- timer.start();
- loop.exec();
- return timer.isActive();
-}
-
// The main point here is to test our access type categorization.
// We do not try to stress-test clangd's "Find References" functionality; such tests belong
// into LLVM.
@@ -110,7 +97,7 @@ void ClangdTests::testFindReferences()
ClangdClient *client = modelManagerSupport->clientForProject(openProjectResult.project());
if (!client) {
QVERIFY(waitForSignalOrTimeout(modelManagerSupport,
- &ClangModelManagerSupport::createdClient));
+ &ClangModelManagerSupport::createdClient, timeOutInMs()));
client = modelManagerSupport->clientForProject(openProjectResult.project());
}
QVERIFY(client);
@@ -119,7 +106,7 @@ void ClangdTests::testFindReferences()
// Wait until the client is fully initialized, i.e. it's completed the handshake
// with the server.
if (!client->reachable())
- QVERIFY(waitForSignalOrTimeout(client, &ClangdClient::initialized));
+ QVERIFY(waitForSignalOrTimeout(client, &ClangdClient::initialized, timeOutInMs()));
QVERIFY(client->reachable());
// The kind of AST support we need was introduced in LLVM 13.
@@ -128,7 +115,7 @@ void ClangdTests::testFindReferences()
// Wait for index to build.
if (!client->isFullyIndexed())
- QVERIFY(waitForSignalOrTimeout(client, &ClangdClient::indexingFinished));
+ QVERIFY(waitForSignalOrTimeout(client, &ClangdClient::indexingFinished, timeOutInMs()));
QVERIFY(client->isFullyIndexed());
// Open cpp documents.
@@ -167,7 +154,7 @@ void ClangdTests::testFindReferences()
cursor.setPosition((pos)); \
searchResults.clear(); \
client->findUsages((doc), cursor, {}); \
- QVERIFY(waitForSignalOrTimeout(client, &ClangdClient::findUsagesDone)); \
+ QVERIFY(waitForSignalOrTimeout(client, &ClangdClient::findUsagesDone, timeOutInMs())); \
} while (false)
#define EXPECT_RESULT(index, lne, col, type) \
diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h
index 1bea80ceca..aadb89483b 100644
--- a/src/plugins/coreplugin/editormanager/editormanager.h
+++ b/src/plugins/coreplugin/editormanager/editormanager.h
@@ -192,6 +192,10 @@ signals:
void autoSaved();
void currentEditorAboutToChange(Core::IEditor *editor);
+#ifdef WITH_TESTS
+ void linkOpened();
+#endif
+
public slots:
static void saveDocument();
static void saveDocumentAs();
diff --git a/src/plugins/cppeditor/CMakeLists.txt b/src/plugins/cppeditor/CMakeLists.txt
index 72d83ef26d..4b4bdd4c15 100644
--- a/src/plugins/cppeditor/CMakeLists.txt
+++ b/src/plugins/cppeditor/CMakeLists.txt
@@ -1,7 +1,7 @@
add_qtc_plugin(CppEditor
DEFINES CPPEDITOR_LIBRARY
PLUGIN_DEPENDS Core CppTools ProjectExplorer TextEditor
- PLUGIN_TEST_DEPENDS QmakeProjectManager
+ PLUGIN_TEST_DEPENDS QbsProjectManager QmakeProjectManager
SOURCES
cppautocompleter.cpp cppautocompleter.h
cppcodemodelinspectordialog.cpp cppcodemodelinspectordialog.h cppcodemodelinspectordialog.ui
diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs
index de9b4d3101..a6c27c30c5 100644
--- a/src/plugins/cppeditor/cppeditor.qbs
+++ b/src/plugins/cppeditor/cppeditor.qbs
@@ -17,6 +17,7 @@ QtcPlugin {
pluginTestDepends: [
"QmakeProjectManager",
+ "QbsProjectManager",
]
files: [
diff --git a/src/plugins/cppeditor/cppeditor_dependencies.pri b/src/plugins/cppeditor/cppeditor_dependencies.pri
index c9a690b079..a17c907490 100644
--- a/src/plugins/cppeditor/cppeditor_dependencies.pri
+++ b/src/plugins/cppeditor/cppeditor_dependencies.pri
@@ -9,4 +9,5 @@ QTC_PLUGIN_DEPENDS += \
cpptools \
projectexplorer
QTC_TEST_DEPENDS += \
+ qbsprojectmanager \
qmakeprojectmanager
diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h
index 523c8e46a5..74a50ad406 100644
--- a/src/plugins/cppeditor/cppeditorplugin.h
+++ b/src/plugins/cppeditor/cppeditorplugin.h
@@ -27,6 +27,10 @@
#include <extensionsystem/iplugin.h>
+#ifdef WITH_TESTS
+namespace ProjectExplorer { class Kit; }
+#endif
+
namespace CppEditor {
namespace Internal {
@@ -49,6 +53,10 @@ public:
CppQuickFixAssistProvider *quickFixProvider() const;
+#ifdef WITH_TESTS
+ ProjectExplorer::Kit *m_testKit = nullptr;
+#endif
+
signals:
void outlineSortingChanged(bool sort);
void typeHierarchyRequested();
@@ -67,6 +75,8 @@ private:
QVector<QObject *> createTestObjects() const override;
private slots:
+ void initTestCase();
+
// The following tests expect that no projects are loaded on start-up.
void test_SwitchMethodDeclarationDefinition_data();
void test_SwitchMethodDeclarationDefinition();
diff --git a/src/plugins/cppeditor/cppeditortestcase.cpp b/src/plugins/cppeditor/cppeditortestcase.cpp
index 027523a02d..b9aaae023a 100644
--- a/src/plugins/cppeditor/cppeditortestcase.cpp
+++ b/src/plugins/cppeditor/cppeditortestcase.cpp
@@ -28,9 +28,12 @@
#include "cppeditor.h"
#include "cppeditorwidget.h"
#include "cppeditordocument.h"
+#include "cppeditorplugin.h"
#include <coreplugin/editormanager/editormanager.h>
+#include <cpptools/cppcodemodelsettings.h>
#include <cpptools/cppsemanticinfo.h>
+#include <cpptools/cpptoolsreuse.h>
#include <cplusplus/CppDocument.h>
#include <QDir>
@@ -74,12 +77,20 @@ bool TestDocument::hasCursorMarker() const { return m_cursorPosition != -1; }
bool TestDocument::hasAnchorMarker() const { return m_anchorPosition != -1; }
TestCase::TestCase(bool runGarbageCollector)
- : CppTools::Tests::TestCase(runGarbageCollector)
+ : CppTools::Tests::TestCase(runGarbageCollector),
+ m_prevUseClangd(CppTools::codeModelSettings()->useClangd())
{
}
TestCase::~TestCase()
{
+ CppTools::codeModelSettings()->setUseClangd(m_prevUseClangd);
+}
+
+void TestCase::setUseClangd()
+{
+ if (CppEditorPlugin::instance()->m_testKit)
+ CppTools::codeModelSettings()->setUseClangd(true);
}
bool TestCase::openCppEditor(const QString &fileName, CppEditor **editor, CppEditorWidget **editorWidget)
diff --git a/src/plugins/cppeditor/cppeditortestcase.h b/src/plugins/cppeditor/cppeditortestcase.h
index 6eb9821bdd..519b7cbafd 100644
--- a/src/plugins/cppeditor/cppeditortestcase.h
+++ b/src/plugins/cppeditor/cppeditortestcase.h
@@ -62,12 +62,17 @@ public:
TestCase(bool runGarbageCollector = true);
~TestCase();
+ void setUseClangd();
+
static bool openCppEditor(const QString &fileName,
CppEditor **editor,
CppEditorWidget **editorWidget = 0);
static CPlusPlus::Document::Ptr waitForRehighlightedSemanticDocument(
CppEditorWidget *editorWidget);
+
+private:
+ const bool m_prevUseClangd;
};
} // namespace Tests
diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp
index 849201d8a5..35f35a3cc3 100644
--- a/src/plugins/cppeditor/cppquickfix_test.cpp
+++ b/src/plugins/cppeditor/cppquickfix_test.cpp
@@ -7185,7 +7185,7 @@ void CppEditorPlugin::test_quickfix_ExtractFunction_data()
"}\n"
"void NS::C::f(NS::C &c)\n"
"{\n"
- " @{start}C *c = &c;@{end}\n"
+ " @{start}C *c2 = &c;@{end}\n"
"}\n")
<< _("namespace NS {\n"
"class C {\n"
@@ -7197,7 +7197,7 @@ void CppEditorPlugin::test_quickfix_ExtractFunction_data()
"}\n"
"inline void NS::C::extracted(NS::C &c)\n"
"{\n"
- " C *c = &c;\n"
+ " C *c2 = &c;\n"
"}\n"
"\n"
"void NS::C::f(NS::C &c)\n"
diff --git a/src/plugins/cppeditor/cppuseselections_test.cpp b/src/plugins/cppeditor/cppuseselections_test.cpp
index 10d6927434..1bf53c3799 100644
--- a/src/plugins/cppeditor/cppuseselections_test.cpp
+++ b/src/plugins/cppeditor/cppuseselections_test.cpp
@@ -28,6 +28,8 @@
#include "cppeditorplugin.h"
#include "cppeditortestcase.h"
+#include <cpptools/cppmodelmanager.h>
+
#include <QElapsedTimer>
#include <QtTest>
@@ -100,11 +102,18 @@ UseSelectionsTestCase::UseSelectionsTestCase(TestDocument &testFile,
bool hasTimedOut;
const SelectionList selections = waitForUseSelections(&hasTimedOut);
- QEXPECT_FAIL("non-local use as macro argument - argument expanded 1", "TODO", Abort);
+ const bool clangCodeModel = CppTools::CppModelManager::instance()->isClangCodeModelActive();
+ if (clangCodeModel) {
+ QEXPECT_FAIL("local use as macro argument - argument eaten", "fails with CCM, find out why",
+ Abort);
+ } else {
+ QEXPECT_FAIL("non-local use as macro argument - argument expanded 1", "TODO", Abort);
+ }
QVERIFY(!hasTimedOut);
// foreach (const Selection &selection, selections)
// qDebug() << QTest::toString(selection);
- QEXPECT_FAIL("non-local use as macro argument - argument expanded 2", "TODO", Abort);
+ if (!clangCodeModel)
+ QEXPECT_FAIL("non-local use as macro argument - argument expanded 2", "TODO", Abort);
QCOMPARE(selections, expectedSelections);
}
diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
index 5cf1e31d29..e6c871f4cd 100644
--- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
+++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
@@ -28,13 +28,18 @@
#include "cppeditorplugin.h"
#include "cppeditortestcase.h"
+#include <cpptools/cppcodemodelsettings.h>
#include <cpptools/cppelementevaluator.h>
#include <cpptools/cppfollowsymbolundercursor.h>
#include <cpptools/cppvirtualfunctionassistprovider.h>
#include <cpptools/cppvirtualfunctionproposalitem.h>
+#include <cpptools/cpptoolsreuse.h>
#include <cpptools/cpptoolstestcase.h>
#include <cpptools/cppmodelmanager.h>
+#include <projectexplorer/kitmanager.h>
+#include <projectexplorer/projectexplorer.h>
+
#include <texteditor/codeassist/genericproposalmodel.h>
#include <texteditor/codeassist/iassistprocessor.h>
#include <texteditor/codeassist/iassistproposal.h>
@@ -76,6 +81,7 @@ using namespace CPlusPlus;
using namespace CppTools;
using namespace TextEditor;
using namespace Core;
+using namespace ProjectExplorer;
class OverrideItem {
public:
@@ -267,6 +273,8 @@ F2TestCase::F2TestCase(CppEditorAction action,
{
QVERIFY(succeededSoFar());
+ setUseClangd();
+
// Check if there are initial and target position markers
TestDocumentPtr initialTestFile = testFileWithInitialCursorMarker(testFiles);
QVERIFY2(initialTestFile,
@@ -275,13 +283,68 @@ F2TestCase::F2TestCase(CppEditorAction action,
QVERIFY2(targetTestFile,
"No test file with target cursor marker is provided.");
+ const QString curTestName = QLatin1String(QTest::currentTestFunction());
+ const QString tag = QLatin1String(QTest::currentDataTag());
+ const bool useClangd = CppTools::codeModelSettings()->useClangd();
+ if (useClangd) {
+ if (curTestName == "test_FollowSymbolUnderCursor_virtualFunctionCall"
+ || curTestName == "test_FollowSymbolUnderCursor_virtualFunctionCall_multipleDocuments") {
+ QSKIP("TODO: Add test infrastructure for this");
+ }
+ if (curTestName == "test_FollowSymbolUnderCursor_QObject_connect"
+ || curTestName == "test_FollowSymbolUnderCursor_QObject_oldStyleConnect") {
+ QSKIP("TODO: Implement fall-back");
+ }
+ if (curTestName == "test_FollowSymbolUnderCursor_classOperator" && tag == "backward")
+ QSKIP("clangd goes to operator name first");
+ if (tag.toLower().contains("fuzzy"))
+ QSKIP("fuzzy matching is not supposed to work with clangd"); // TODO: Implement fallback as we do with libclang
+ if (tag == "baseClassFunctionIntroducedByUsingDeclaration")
+ QSKIP("clangd points to the using declaration");
+ if (tag == "classDestructor")
+ QSKIP("clangd wants the cursor before the ~ character");
+ if (curTestName == "test_FollowSymbolUnderCursor_classOperator_inOp")
+ QSKIP("clangd goes to operator name first");
+ if (tag == "fromFunctionBody" || tag == "fromReturnType"
+ || tag == "conversionOperatorDecl2Def") {
+ QSKIP("TODO: explicit decl/def switch not yet supported with clangd");
+ }
+ }
+
// Write files to disk
CppTools::Tests::TemporaryDir temporaryDir;
QVERIFY(temporaryDir.isValid());
+ QString projectFileContent = "CppApplication { files: [";
foreach (TestDocumentPtr testFile, testFiles) {
QVERIFY(testFile->baseDirectory().isEmpty());
testFile->setBaseDirectory(temporaryDir.path());
QVERIFY(testFile->writeToDisk());
+ projectFileContent += QString::fromLatin1("\"%1\",").arg(testFile->filePath());
+ }
+ projectFileContent += "]}\n";
+
+ class ProjectCloser {
+ public:
+ void setProject(Project *p) { m_p = p; }
+ ~ProjectCloser() { if (m_p) ProjectExplorerPlugin::unloadProject(m_p); }
+ private:
+ Project * m_p = nullptr;
+ } projectCloser;
+
+ if (useClangd) {
+ TestDocument projectFile(projectFileContent.toUtf8(), "project.qbs");
+ projectFile.setBaseDirectory(temporaryDir.path());
+ QVERIFY(projectFile.writeToDisk());
+ const auto openProjectResult = ProjectExplorerPlugin::openProject(projectFile.filePath());
+ QVERIFY2(openProjectResult && openProjectResult.project(),
+ qPrintable(openProjectResult.errorMessage()));
+ projectCloser.setProject(openProjectResult.project());
+ openProjectResult.project()->configureAsExampleProject(
+ CppEditorPlugin::instance()->m_testKit);
+
+ // Wait until project is fully indexed.
+ QVERIFY(CppTools::Tests::waitForSignalOrTimeout(openProjectResult.project(),
+ &Project::indexingFinished, CppTools::Tests::clangdIndexingTimeout()));
}
// Update Code Model
@@ -294,7 +357,8 @@ F2TestCase::F2TestCase(CppEditorAction action,
foreach (TestDocumentPtr testFile, testFiles) {
QVERIFY(openCppEditor(testFile->filePath(), &testFile->m_editor,
&testFile->m_editorWidget));
- closeEditorAtEndOfTestCase(testFile->m_editor);
+ if (!useClangd) // Editors get closed when unloading project.
+ closeEditorAtEndOfTestCase(testFile->m_editor);
// Wait until the indexer processed the just opened file.
// The file is "Full Checked" since it is in the working copy now,
@@ -303,13 +367,16 @@ F2TestCase::F2TestCase(CppEditorAction action,
const Document::Ptr document = waitForFileInGlobalSnapshot(testFile->filePath());
QVERIFY(document);
if (document->checkMode() == Document::FullCheck) {
+ if (!document->diagnosticMessages().isEmpty())
+ qDebug() << document->diagnosticMessages().first().text();
QVERIFY(document->diagnosticMessages().isEmpty());
break;
}
}
// Rehighlight
- waitForRehighlightedSemanticDocument(testFile->m_editorWidget);
+ if (!useClangd)
+ waitForRehighlightedSemanticDocument(testFile->m_editorWidget);
}
// Activate editor of initial test file
@@ -329,14 +396,8 @@ F2TestCase::F2TestCase(CppEditorAction action,
FollowSymbolInterface &delegate = CppModelManager::instance()->followSymbolInterface();
auto* builtinFollowSymbol = dynamic_cast<FollowSymbolUnderCursor *>(&delegate);
if (!builtinFollowSymbol) {
- if (filePaths.size() > 1)
- QSKIP("Clang FollowSymbol does not currently support multiple files (except cpp+header)");
- const QString curTestName = QLatin1String(QTest::currentTestFunction());
- if (curTestName == "test_FollowSymbolUnderCursor_QObject_connect"
- || curTestName == "test_FollowSymbolUnderCursor_virtualFunctionCall"
- || curTestName == "test_FollowSymbolUnderCursor_QTCREATORBUG7903") {
+ if (curTestName == "test_FollowSymbolUnderCursor_QTCREATORBUG7903")
QSKIP((curTestName + " is not supported by Clang FollowSymbol").toLatin1());
- }
widget->openLinkUnderCursor();
break;
@@ -358,14 +419,24 @@ F2TestCase::F2TestCase(CppEditorAction action,
break;
}
case SwitchBetweenMethodDeclarationDefinitionAction:
- CppEditorPlugin::instance()->switchDeclarationDefinition();
+ if (CppTools::codeModelSettings()->useClangd())
+ initialTestFile->m_editorWidget->openLinkUnderCursor();
+ else
+ CppEditorPlugin::instance()->switchDeclarationDefinition();
break;
default:
QFAIL("Unknown test action");
break;
}
- QCoreApplication::processEvents();
+ if (useClangd) {
+ QEXPECT_FAIL("infiniteLoopLocalTypedef_QTCREATORBUG-11999",
+ "clangd bug: Go to definition does not return", Abort);
+ QVERIFY(CppTools::Tests::waitForSignalOrTimeout(EditorManager::instance(),
+ &EditorManager::linkOpened, 10000));
+ } else {
+ QCoreApplication::processEvents();
+ }
// Compare
IEditor *currentEditor = EditorManager::currentEditor();
@@ -379,8 +450,11 @@ F2TestCase::F2TestCase(CppEditorAction action,
// qDebug() << "Expected line:" << expectedLine;
// qDebug() << "Expected column:" << expectedColumn;
- QEXPECT_FAIL("globalVarFromEnum", "Contributor works on a fix.", Abort);
- QEXPECT_FAIL("matchFunctionSignature_Follow_5", "foo(int) resolved as CallAST", Abort);
+ if (!CppTools::codeModelSettings()->useClangd()) {
+ QEXPECT_FAIL("globalVarFromEnum", "Contributor works on a fix.", Abort);
+ QEXPECT_FAIL("matchFunctionSignature_Follow_5", "foo(int) resolved as CallAST", Abort);
+ }
+
QCOMPARE(currentTextEditor->currentLine(), expectedLine);
QCOMPARE(currentTextEditor->currentColumn(), expectedColumn);
@@ -421,6 +495,25 @@ Q_DECLARE_METATYPE(QList<CppEditor::Internal::TestDocumentPtr>)
namespace CppEditor {
namespace Internal {
+void CppEditorPlugin::initTestCase()
+{
+ const auto settings = CppTools::codeModelSettings();
+ const QString clangdFromEnv = qEnvironmentVariable("QTC_CLANGD");
+ if (clangdFromEnv.isEmpty())
+ return;
+ settings->setClangdFilePath(Utils::FilePath::fromString(clangdFromEnv));
+ const auto clangd = settings->clangdFilePath();
+ if (clangd.isEmpty() || !clangd.exists())
+ return;
+
+ // Find suitable kit.
+ m_testKit = Utils::findOr(KitManager::kits(), nullptr, [](const Kit *k) {
+ return k->isValid();
+ });
+ if (!m_testKit)
+ QSKIP("This test requires at least one kit to be present");
+}
+
void CppEditorPlugin::test_SwitchMethodDeclarationDefinition_data()
{
QTest::addColumn<QByteArray>("header");
@@ -576,7 +669,6 @@ void CppEditorPlugin::test_SwitchMethodDeclarationDefinition_data()
"int OtherClass::var;\n"
"namespace NS {\n"
"int OtherClass::var;\n"
- "float Test::var;\n"
"int Test::$var;\n"
"}\n");
@@ -1276,7 +1368,6 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_multipleDocuments_data()
"int OtherClass::var;\n"
"namespace NS {\n"
"int OtherClass::var;\n"
- "float Test::var;\n"
"int Test::$var;\n"
"}\n", "file.cpp")};
}
diff --git a/src/plugins/cpptools/cpptoolstestcase.cpp b/src/plugins/cpptools/cpptoolstestcase.cpp
index 8a714b7df7..c80a4a7cff 100644
--- a/src/plugins/cpptools/cpptoolstestcase.cpp
+++ b/src/plugins/cpptools/cpptoolstestcase.cpp
@@ -44,6 +44,7 @@
#include <cplusplus/CppDocument.h>
#include <utils/executeondestruction.h>
#include <utils/fileutils.h>
+#include <utils/hostosinfo.h>
#include <utils/temporarydirectory.h>
#include <QtTest>
@@ -421,5 +422,15 @@ bool VerifyCleanCppModelManager::isClean(bool testOnlyForCleanedProjects)
#undef RETURN_FALSE_IF_NOT
+int clangdIndexingTimeout()
+{
+ const QByteArray timeoutAsByteArray = qgetenv("QTC_CLANGD_INDEXING_TIMEOUT");
+ bool isConversionOk = false;
+ const int intervalAsInt = timeoutAsByteArray.toInt(&isConversionOk);
+ if (!isConversionOk)
+ return Utils::HostOsInfo::isWindowsHost() ? 20000 : 10000;
+ return intervalAsInt;
+}
+
} // namespace Tests
} // namespace CppTools
diff --git a/src/plugins/cpptools/cpptoolstestcase.h b/src/plugins/cpptools/cpptoolstestcase.h
index aaa94f1e07..08ae5b7c70 100644
--- a/src/plugins/cpptools/cpptoolstestcase.h
+++ b/src/plugins/cpptools/cpptoolstestcase.h
@@ -30,7 +30,9 @@
#include <cplusplus/CppDocument.h>
#include <utils/temporarydirectory.h>
+#include <QEventLoop>
#include <QStringList>
+#include <QTimer>
namespace CPlusPlus {
class Document;
@@ -54,6 +56,23 @@ class ProjectInfo;
namespace Tests {
+int CPPTOOLS_EXPORT clangdIndexingTimeout();
+
+template <typename Signal> inline bool waitForSignalOrTimeout(
+ const typename QtPrivate::FunctionPointer<Signal>::Object *sender, Signal signal,
+ int timeoutInMs)
+{
+ QTimer timer;
+ timer.setSingleShot(true);
+ timer.setInterval(timeoutInMs);
+ QEventLoop loop;
+ QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
+ QObject::connect(sender, signal, &loop, &QEventLoop::quit);
+ timer.start();
+ loop.exec();
+ return timer.isActive();
+}
+
class CPPTOOLS_EXPORT TestDocument
{
public:
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index 31cb6e12b9..fd550b5eab 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -212,6 +212,10 @@ signals:
void rootProjectDirectoryChanged();
+#ifdef WITH_TESTS
+ void indexingFinished(Utils::Id indexer);
+#endif
+
protected:
virtual RestoreResult fromMap(const QVariantMap &map, QString *errorMessage);
void createTargetFromMap(const QVariantMap &map, int index);
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index 033dd2a58a..69d11f2747 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -6257,6 +6257,10 @@ void TextEditorWidget::findLinkAt(const QTextCursor &cursor,
bool TextEditorWidget::openLink(const Utils::Link &link, bool inNextSplit)
{
+#ifdef WITH_TESTS
+ struct Signaller { ~Signaller() { emit EditorManager::instance()->linkOpened(); } } s;
+#endif
+
if (!link.hasValidTarget())
return false;