diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2022-04-28 19:39:51 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2022-05-04 10:04:17 +0000 |
commit | 5f9cbe7fe8da790380aefdfe65efedb1b1434cbf (patch) | |
tree | b0526965b264cfa367e750fa28fdcea4048098b6 | |
parent | 4b0b3e9e353aad8a3aaa444ff7748c91ae666c58 (diff) |
Remove clangbackend
Change-Id: I5f4f9a2fc5469c4eeb112a46626791ffb9a57a85
Reviewed-by: David Schulz <david.schulz@qt.io>
162 files changed, 0 insertions, 27025 deletions
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index c9ee827bd9..d10b520d9d 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -1,10 +1,5 @@ add_subdirectory(3rdparty) add_subdirectory(buildoutputparser) -if (NOT Clang_FOUND) - message(WARNING "Could not find Clang installation - disabling clangbackend.") -else () - add_subdirectory(clangbackend) -endif () option(BUILD_CPLUSPLUS_TOOLS "Build CPlusPlus tools" OFF) diff --git a/src/tools/clangbackend/CMakeLists.txt b/src/tools/clangbackend/CMakeLists.txt deleted file mode 100644 index c0ad4e864d..0000000000 --- a/src/tools/clangbackend/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_subdirectory(source) - -add_qtc_executable(clangbackend - DEPENDS Qt5::Core Qt5::Network clangbackend_lib Sqlite ClangSupport libclang - SOURCES - ../qtcreatorcrashhandler/crashhandlersetup.cpp ../qtcreatorcrashhandler/crashhandlersetup.h - clangbackendmain.cpp -) diff --git a/src/tools/clangbackend/clangbackend.qbs b/src/tools/clangbackend/clangbackend.qbs deleted file mode 100644 index 495c586f85..0000000000 --- a/src/tools/clangbackend/clangbackend.qbs +++ /dev/null @@ -1,38 +0,0 @@ -import qbs 1.0 - -QtcTool { - name: "clangbackend" - - Depends { name: "ClangSupport" } - Depends { name: "libclang"; required: false } - - Group { - prefix: "source/" - files: [ - "*.h", - "*.cpp" - ] - } - - Group { - prefix: "../qtcreatorcrashhandler/" - files: [ - "crashhandlersetup.cpp", - "crashhandlersetup.h", - ] - } - - files: [ "clangbackendmain.cpp" ] - - condition: libclang.present - - cpp.includePaths: base.concat(["source", libclang.llvmIncludeDir]) - cpp.libraryPaths: base.concat(libclang.llvmLibDir) - cpp.dynamicLibraries: base.concat(libclang.llvmLibs) - cpp.rpaths: base.concat(libclang.llvmLibDir) - - Properties { - condition: qbs.targetOS.contains("unix") && !qbs.targetOS.contains("macos") - cpp.linkerFlags: base.concat(["-z", "origin"]) - } -} diff --git a/src/tools/clangbackend/clangbackendmain.cpp b/src/tools/clangbackend/clangbackendmain.cpp deleted file mode 100644 index 18db148893..0000000000 --- a/src/tools/clangbackend/clangbackendmain.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "../qtcreatorcrashhandler/crashhandlersetup.h" - -#include <QCommandLineParser> -#include <QCoreApplication> -#include <QLoggingCategory> - -#include <connectionserver.h> -#include <clangcodemodelserver.h> -#include <clangcodemodelclientproxy.h> - -#include <iostream> -#include <clocale> - -using ClangBackEnd::ClangCodeModelClientProxy; -using ClangBackEnd::ClangCodeModelServer; -using ClangBackEnd::ConnectionServer; - -QString processArguments(QCoreApplication &application) -{ - QCommandLineParser parser; - parser.setApplicationDescription(QStringLiteral("Qt Creator Clang backend process.")); - parser.addHelpOption(); - parser.addVersionOption(); - parser.addPositionalArgument(QStringLiteral("connection"), QStringLiteral("Connection")); - - parser.process(application); - - if (parser.positionalArguments().isEmpty()) - parser.showHelp(1); - - return parser.positionalArguments().constFirst(); -} - -#ifdef Q_OS_WIN -#include <windows.h> -static void messageOutput(QtMsgType type, const QMessageLogContext &/*context*/, - const QString &msg) -{ - OutputDebugStringW(msg.toStdWString().c_str()); - std::wcout << msg.toStdWString() << std::endl; - if (type == QtFatalMsg) - abort(); -} -#endif - -int main(int argc, char *argv[]) -{ -#ifdef Q_OS_WIN - qInstallMessageHandler(&messageOutput); -#endif - QCoreApplication::setOrganizationName(QStringLiteral("QtProject")); - QCoreApplication::setOrganizationDomain(QStringLiteral("qt-project.org")); - QCoreApplication::setApplicationName(QStringLiteral("ClangBackend")); - QCoreApplication::setApplicationVersion(QStringLiteral("1.0.0")); - - QCoreApplication application(argc, argv); - - // Some tidy checks use locale-dependent conversion functions and thus might throw exceptions. - std::setlocale(LC_NUMERIC, "C"); - - CrashHandlerSetup setupCrashHandler(QCoreApplication::applicationName(), - CrashHandlerSetup::DisableRestart); - - const QString connection = processArguments(application); - - // Printing the stack strace might dead lock as clang's stack printer allocates memory. - if (qEnvironmentVariableIntValue("QTC_CLANG_ENABLE_STACKTRACES")) - clang_enableStackTraces(); - - ClangCodeModelServer clangCodeModelServer; - ConnectionServer<ClangCodeModelServer, ClangCodeModelClientProxy> connectionServer; - connectionServer.setServer(&clangCodeModelServer); - connectionServer.start(connection); - - return application.exec(); -} - - diff --git a/src/tools/clangbackend/source/CMakeLists.txt b/src/tools/clangbackend/source/CMakeLists.txt deleted file mode 100644 index 4a3c115a5c..0000000000 --- a/src/tools/clangbackend/source/CMakeLists.txt +++ /dev/null @@ -1,74 +0,0 @@ -add_qtc_library(clangbackend_lib STATIC - DEPENDS libclang - PUBLIC_DEPENDS - Qt5::Widgets # FIXME: change the way to get the gui pch to linkto - PUBLIC_DEFINES - $<TARGET_PROPERTY:ClangSupport,INTERFACE_COMPILE_DEFINITIONS> - $<TARGET_PROPERTY:Sqlite,INTERFACE_COMPILE_DEFINITIONS> - INCLUDES - $<TARGET_PROPERTY:ClangSupport,INTERFACE_INCLUDE_DIRECTORIES> - $<TARGET_PROPERTY:Sqlite,INTERFACE_INCLUDE_DIRECTORIES> - PUBLIC_INCLUDES - ${CLANG_INCLUDE_DIRS} - "${CMAKE_CURRENT_LIST_DIR}" - SOURCES - clangasyncjob.h - clangbackend_global.h - clangclock.h - clangcodecompleteresults.cpp clangcodecompleteresults.h - clangcodemodelserver.cpp clangcodemodelserver.h - clangcompletecodejob.cpp clangcompletecodejob.h - clangdocument.cpp clangdocument.h - clangdocumentjob.h - clangdocumentprocessor.cpp clangdocumentprocessor.h - clangdocumentprocessors.cpp clangdocumentprocessors.h - clangdocuments.cpp clangdocuments.h - clangdocumentsuspenderresumer.cpp clangdocumentsuspenderresumer.h - clangexceptions.cpp clangexceptions.h - clangfilepath.cpp clangfilepath.h - clangfilesystemwatcher.cpp clangfilesystemwatcher.h - clangfollowsymbol.cpp clangfollowsymbol.h - clangfollowsymboljob.cpp clangfollowsymboljob.h - clangiasyncjob.cpp clangiasyncjob.h - clangjobcontext.cpp clangjobcontext.h - clangjobqueue.cpp clangjobqueue.h - clangjobrequest.cpp clangjobrequest.h - clangjobs.cpp clangjobs.h - clangparsesupportivetranslationunitjob.cpp clangparsesupportivetranslationunitjob.h - clangreferencescollector.cpp clangreferencescollector.h - clangrequestannotationsjob.cpp clangrequestannotationsjob.h - clangrequestreferencesjob.cpp clangrequestreferencesjob.h - clangrequesttooltipjob.cpp clangrequesttooltipjob.h - clangresumedocumentjob.cpp clangresumedocumentjob.h - clangstring.h - clangsupportivetranslationunitinitializer.cpp clangsupportivetranslationunitinitializer.h - clangsuspenddocumentjob.cpp clangsuspenddocumentjob.h - clangtooltipinfocollector.cpp clangtooltipinfocollector.h - clangtranslationunit.cpp clangtranslationunit.h - clangtranslationunits.cpp clangtranslationunits.h - clangtranslationunitupdater.cpp clangtranslationunitupdater.h - clangtype.cpp clangtype.h - clangunsavedfilesshallowarguments.cpp clangunsavedfilesshallowarguments.h - clangupdateannotationsjob.cpp clangupdateannotationsjob.h - clangupdateextraannotationsjob.cpp clangupdateextraannotationsjob.h - codecompleter.cpp codecompleter.h - codecompletionchunkconverter.cpp codecompletionchunkconverter.h - codecompletionsextractor.cpp codecompletionsextractor.h - commandlinearguments.cpp commandlinearguments.h - cursor.cpp cursor.h - diagnostic.cpp diagnostic.h - diagnosticset.cpp diagnosticset.h - diagnosticsetiterator.h - fixit.cpp fixit.h - fulltokeninfo.cpp fulltokeninfo.h - skippedsourceranges.cpp skippedsourceranges.h - sourcelocation.cpp sourcelocation.h - sourcerange.cpp sourcerange.h - token.cpp token.h - tokeninfo.cpp tokeninfo.h - tokenprocessor.h - tokenprocessoriterator.h - unsavedfile.cpp unsavedfile.h - unsavedfiles.cpp unsavedfiles.h - utf8positionfromlinecolumn.cpp utf8positionfromlinecolumn.h -) diff --git a/src/tools/clangbackend/source/clangasyncjob.h b/src/tools/clangbackend/source/clangasyncjob.h deleted file mode 100644 index 9299658aa4..0000000000 --- a/src/tools/clangbackend/source/clangasyncjob.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangiasyncjob.h" - -#include <utils/runextensions.h> - -#include <QFutureWatcher> -#include <QObject> - -namespace ClangBackEnd { - -template<class Result> -class AsyncJob : public IAsyncJob -{ -public: - AsyncJob() {} - ~AsyncJob() {} - - using Runner = std::function<Result()>; - Runner runner() const { return m_runner; } - void setRunner(const Runner &runner) { m_runner = runner; } - - Result asyncResult() const { return m_futureWatcher.future().result(); } - - QFuture<void> runAsync() final - { - const auto onFinished = [this]() { - finalizeAsyncRun(); - setIsFinished(true); - finishedHandler()(this); - }; - QObject::connect(&m_futureWatcher, - &QFutureWatcher<Result>::finished, - onFinished); - - // Use 16MB stack size as clang_annotateTokens() would with an internal thread. - const Utils::StackSizeInBytes stackSize = 1024 * 1024 * 16; - const QFuture<Result> future = Utils::runAsync(stackSize, m_runner); - m_futureWatcher.setFuture(future); - - return QFuture<void>(future); - } - - void preventFinalization() final - { - m_futureWatcher.disconnect(); - } - -private: - Runner m_runner; - QFutureWatcher<Result> m_futureWatcher; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangbackend_global.h b/src/tools/clangbackend/source/clangbackend_global.h deleted file mode 100644 index e62c9a3513..0000000000 --- a/src/tools/clangbackend/source/clangbackend_global.h +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -enum class PreferredTranslationUnit -{ - RecentlyParsed, - PreviouslyParsed, - LastUninitialized, -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangclock.h b/src/tools/clangbackend/source/clangclock.h deleted file mode 100644 index 68d91478f7..0000000000 --- a/src/tools/clangbackend/source/clangclock.h +++ /dev/null @@ -1,36 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <chrono> - -namespace ClangBackEnd { - -using Clock = std::chrono::steady_clock; -using Duration = std::chrono::steady_clock::duration; -using TimePoint = std::chrono::steady_clock::time_point; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangcodecompleteresults.cpp b/src/tools/clangbackend/source/clangcodecompleteresults.cpp deleted file mode 100644 index 818aa9360e..0000000000 --- a/src/tools/clangbackend/source/clangcodecompleteresults.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangcodecompleteresults.h" - -#include <memory> - -namespace ClangBackEnd { - -using std::swap; - -ClangCodeCompleteResults::ClangCodeCompleteResults(CXCodeCompleteResults *cxCodeCompleteResults) - : cxCodeCompleteResults(cxCodeCompleteResults) -{ -} - -ClangCodeCompleteResults::~ClangCodeCompleteResults() -{ - clang_disposeCodeCompleteResults(cxCodeCompleteResults); -} - -bool ClangCodeCompleteResults::isNull() const -{ - return cxCodeCompleteResults == nullptr; -} - -bool ClangCodeCompleteResults::isEmpty() const -{ - return cxCodeCompleteResults->NumResults == 0; -} - -bool ClangCodeCompleteResults::hasResults() const -{ - return !isNull() && !isEmpty(); -} - -bool ClangCodeCompleteResults::hasUnknownContext() const -{ - const unsigned long long contexts = clang_codeCompleteGetContexts(cxCodeCompleteResults); - return contexts == CXCompletionContext_Unknown; -} - -CXCodeCompleteResults *ClangCodeCompleteResults::data() const -{ - return cxCodeCompleteResults; -} - -ClangCodeCompleteResults &ClangCodeCompleteResults::operator=(ClangCodeCompleteResults &&clangCodeCompleteResults) -{ - swap(cxCodeCompleteResults, clangCodeCompleteResults.cxCodeCompleteResults); - - return *this; -} - -ClangCodeCompleteResults::ClangCodeCompleteResults(ClangCodeCompleteResults &&clangCodeCompleteResults) -{ - swap(cxCodeCompleteResults, clangCodeCompleteResults.cxCodeCompleteResults); -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/clangcodecompleteresults.h b/src/tools/clangbackend/source/clangcodecompleteresults.h deleted file mode 100644 index 000c424b33..0000000000 --- a/src/tools/clangbackend/source/clangcodecompleteresults.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <clang-c/Index.h> - -#include <utf8string.h> - -namespace ClangBackEnd { - -class ClangCodeCompleteResults -{ -public: - ClangCodeCompleteResults() = default; - - ClangCodeCompleteResults(CXCodeCompleteResults *cxCodeCompleteResults); - ~ClangCodeCompleteResults(); - - ClangCodeCompleteResults(const ClangCodeCompleteResults &ClangCodeCompleteResults) = delete; - const ClangCodeCompleteResults &operator=(const ClangCodeCompleteResults &ClangCodeCompleteResults) = delete; - - ClangCodeCompleteResults(ClangCodeCompleteResults &&ClangCodeCompleteResults); - ClangCodeCompleteResults &operator=(ClangCodeCompleteResults &&ClangCodeCompleteResults); - - bool isNull() const; - bool isEmpty() const; - - bool hasResults() const; - - bool hasUnknownContext() const; - - CXCodeCompleteResults *data() const; - -private: - CXCodeCompleteResults *cxCodeCompleteResults = nullptr; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangcodemodelserver.cpp b/src/tools/clangbackend/source/clangcodemodelserver.cpp deleted file mode 100644 index a647b0e649..0000000000 --- a/src/tools/clangbackend/source/clangcodemodelserver.cpp +++ /dev/null @@ -1,520 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangcodemodelserver.h" - -#include "clangdocuments.h" -#include "clangdocumentsuspenderresumer.h" -#include "clangfilesystemwatcher.h" -#include "clangupdateannotationsjob.h" -#include "codecompleter.h" -#include "diagnosticset.h" -#include "tokenprocessor.h" -#include "clangexceptions.h" -#include "skippedsourceranges.h" -#include "unsavedfile.h" - -#include <clangsupport/clangsupportdebugutils.h> -#include <clangsupport/clangcodemodelservermessages.h> - -#include <utils/algorithm.h> -#include <utils/qtcassert.h> - -#include <QCoreApplication> -#include <QDebug> -#include <QFileInfo> -#include <QLoggingCategory> -#include <QDir> - -static Q_LOGGING_CATEGORY(serverLog, "qtc.clangbackend.server", QtWarningMsg); - -static bool useSupportiveTranslationUnit() -{ - static bool use = !qEnvironmentVariableIntValue("QTC_CLANG_NO_SUPPORTIVE_TRANSLATIONUNIT"); - return use; -} - -namespace ClangBackEnd { - -ClangCodeModelServer::ClangCodeModelServer() - : documents(unsavedFiles) -{ - updateAnnotationsTimer.setSingleShot(true); - QObject::connect(&updateAnnotationsTimer, - &QTimer::timeout, - [this]() { - processJobsForVisibleDocuments(); - }); - - updateVisibleButNotCurrentDocumentsTimer.setSingleShot(true); - QObject::connect(&updateVisibleButNotCurrentDocumentsTimer, - &QTimer::timeout, - [this]() { - addAndRunUpdateJobs(documents.dirtyAndVisibleButNotCurrentDocuments()); - }); - - QObject::connect(documents.clangFileSystemWatcher(), - &ClangFileSystemWatcher::fileChanged, - [this](const Utf8String &filePath) { - if (!documents.hasDocument(filePath)) - updateAnnotationsTimer.start(0); - }); -} - -void ClangCodeModelServer::end() -{ - QCoreApplication::exit(); -} - -void ClangCodeModelServer::documentsOpened(const ClangBackEnd::DocumentsOpenedMessage &message) -{ - qCDebug(serverLog) << "########## documentsOpened"; - TIME_SCOPE_DURATION("ClangCodeModelServer::documentsOpened"); - - try { - DocumentResetInfos toReset; - QVector<FileContainer> toCreate; - categorizeFileContainers(message.fileContainers, toCreate, toReset); - - std::vector<Document> createdDocuments = documents.create(toCreate); - for (auto &document : createdDocuments) { - document.setDirtyIfDependencyIsMet(document.filePath()); - DocumentProcessor processor = documentProcessors().create(document); - processor.jobs().setJobFinishedCallback([this](const Jobs::RunningJob &a, IAsyncJob *b) { - return onJobFinished(a, b); - }); - } - const std::vector<Document> resetDocuments_ = resetDocuments(toReset); - - unsavedFiles.createOrUpdate(message.fileContainers); - documents.setUsedByCurrentEditor(message.currentEditorFilePath); - documents.setVisibleInEditors(message.visibleEditorFilePaths); - - processSuspendResumeJobs(documents.documents()); - processJobsForVisibleDocuments(); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::documentsOpened:" << exception.what(); - } -} - -void ClangCodeModelServer::documentsChanged(const DocumentsChangedMessage &message) -{ - qCDebug(serverLog) << "########## documentsChanged"; - TIME_SCOPE_DURATION("ClangCodeModelServer::documentsChanged"); - - try { - const auto newerFileContainers = documents.newerFileContainers(message.fileContainers); - if (newerFileContainers.size() > 0) { - std::vector<Document> updateDocuments = documents.update(newerFileContainers); - unsavedFiles.createOrUpdate(newerFileContainers); - - for (Document &document : updateDocuments) { - if (!document.isResponsivenessIncreased()) - document.setResponsivenessIncreaseNeeded(true); - } - - // Start the jobs on the next event loop iteration since otherwise - // we might block the translation unit for a completion request - // that comes right after this message. - updateAnnotationsTimer.start(0); - } - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::documentsChanged:" << exception.what(); - } -} - -void ClangCodeModelServer::documentsClosed(const ClangBackEnd::DocumentsClosedMessage &message) -{ - qCDebug(serverLog) << "########## documentsClosed"; - TIME_SCOPE_DURATION("ClangCodeModelServer::documentsClosed"); - - try { - for (const auto &fileContainer : message.fileContainers) { - const Document &document = documents.document(fileContainer); - documentProcessors().remove(document); - } - documents.remove(message.fileContainers); - unsavedFiles.remove(message.fileContainers); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::documentsClosed:" << exception.what(); - } -} - -void ClangCodeModelServer::unsavedFilesUpdated(const UnsavedFilesUpdatedMessage &message) -{ - qCDebug(serverLog) << "########## unsavedFilesUpdated"; - TIME_SCOPE_DURATION("ClangCodeModelServer::unsavedFilesUpdated"); - - try { - unsavedFiles.createOrUpdate(message.fileContainers); - documents.updateDocumentsWithChangedDependencies(message.fileContainers); - resetDocumentsWithUnresolvedIncludes(documents.documents()); - - updateAnnotationsTimer.start(updateAnnotationsTimeOutInMs); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::unsavedFilesUpdated:" << exception.what(); - } -} - -void ClangCodeModelServer::unsavedFilesRemoved(const UnsavedFilesRemovedMessage &message) -{ - qCDebug(serverLog) << "########## unsavedFilesRemoved"; - TIME_SCOPE_DURATION("ClangCodeModelServer::unsavedFilesRemoved"); - - try { - unsavedFiles.remove(message.fileContainers); - documents.updateDocumentsWithChangedDependencies(message.fileContainers); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::unsavedFilesRemoved:" << exception.what(); - } -} - -void ClangCodeModelServer::requestCompletions(const ClangBackEnd::RequestCompletionsMessage &message) -{ - qCDebug(serverLog) << "########## requestCompletions"; - TIME_SCOPE_DURATION("ClangCodeModelServer::requestCompletions"); - - try { - Document document = documents.document(message.filePath); - DocumentProcessor processor = documentProcessors().processor(document); - - JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::RequestCompletions); - jobRequest.line = message.line; - jobRequest.column = message.column; - jobRequest.funcNameStartLine = message.funcNameStartLine; - jobRequest.funcNameStartColumn = message.funcNameStartColumn; - jobRequest.ticketNumber = message.ticketNumber; - - processor.addJob(jobRequest); - processor.process(); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::requestCompletions:" << exception.what(); - } -} - -void ClangCodeModelServer::requestAnnotations(const RequestAnnotationsMessage &message) -{ - qCDebug(serverLog) << "########## requestAnnotations"; - TIME_SCOPE_DURATION("ClangCodeModelServer::requestAnnotations"); - - try { - auto document = documents.document(message.fileContainer.filePath); - - DocumentProcessor processor = documentProcessors().processor(document); - processor.addJob(JobRequest::Type::RequestAnnotations); - processor.addJob(JobRequest::Type::UpdateExtraAnnotations); - processor.process(); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::requestAnnotations:" << exception.what(); - } -} - -template <class MessageType> -static void fillJobRequest(JobRequest &jobRequest, const MessageType &message) -{ - jobRequest.line = message.line; - jobRequest.column = message.column; - jobRequest.ticketNumber = message.ticketNumber; - jobRequest.textCodecName = message.fileContainer.textCodecName; - // The unsaved files might get updater later, so take the current - // revision for the request. - jobRequest.documentRevision = message.fileContainer.documentRevision; -} - -void ClangCodeModelServer::requestReferences(const RequestReferencesMessage &message) -{ - qCDebug(serverLog) << "########## requestReferences"; - TIME_SCOPE_DURATION("ClangCodeModelServer::requestReferences"); - - try { - const Document document = documents.document(message.fileContainer.filePath); - DocumentProcessor processor = documentProcessors().processor(document); - - JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::RequestReferences); - fillJobRequest(jobRequest, message); - jobRequest.localReferences = message.local; - processor.addJob(jobRequest); - processor.process(); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::requestReferences:" << exception.what(); - } -} - -void ClangCodeModelServer::requestFollowSymbol(const RequestFollowSymbolMessage &message) -{ - qCDebug(serverLog) << "########## requestFollowSymbol"; - TIME_SCOPE_DURATION("ClangCodeModelServer::requestFollowSymbol"); - - try { - Document document = documents.document(message.fileContainer.filePath); - DocumentProcessor processor = documentProcessors().processor(document); - - JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::RequestFollowSymbol); - fillJobRequest(jobRequest, message); - processor.addJob(jobRequest); - processor.process(); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::requestFollowSymbol:" << exception.what(); - } -} - -void ClangCodeModelServer::requestToolTip(const RequestToolTipMessage &message) -{ - TIME_SCOPE_DURATION("ClangCodeModelServer::requestToolTip"); - - try { - const Document document = documents.document(message.fileContainer.filePath); - DocumentProcessor processor = documentProcessors().processor(document); - - JobRequest jobRequest = processor.createJobRequest(JobRequest::Type::RequestToolTip); - fillJobRequest(jobRequest, message); - - processor.addJob(jobRequest); - processor.process(); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::requestToolTip:" << exception.what(); - } -} - -void ClangCodeModelServer::documentVisibilityChanged(const DocumentVisibilityChangedMessage &message) -{ - qCDebug(serverLog) << "########## documentVisibilityChanged"; - TIME_SCOPE_DURATION("ClangCodeModelServer::documentVisibilityChanged"); - - try { - documents.setUsedByCurrentEditor(message.currentEditorFilePath); - documents.setVisibleInEditors(message.visibleEditorFilePaths); - processSuspendResumeJobs(documents.documents()); - - updateAnnotationsTimer.start(0); - } catch (const std::exception &exception) { - qWarning() << "Error in ClangCodeModelServer::documentVisibilityChanged:" << exception.what(); - } -} - -const Documents &ClangCodeModelServer::documentsForTestOnly() const -{ - return documents; -} - -QList<Jobs::RunningJob> ClangCodeModelServer::runningJobsForTestsOnly() -{ - return documentProcessors().runningJobs(); -} - -int ClangCodeModelServer::queueSizeForTestsOnly() -{ - return documentProcessors().queueSize(); -} - -bool ClangCodeModelServer::isTimerRunningForTestOnly() const -{ - return updateAnnotationsTimer.isActive(); -} - -void ClangCodeModelServer::processJobsForVisibleDocuments() -{ - processJobsForCurrentDocument(); - processTimerForVisibleButNotCurrentDocuments(); -} - -void ClangCodeModelServer::processJobsForCurrentDocument() -{ - auto currentDocuments = documents.filtered([](const Document &document) { - return document.isUsedByCurrentEditor() && document.isDirty(); - }); - QTC_CHECK(currentDocuments.size() <= 1); - - addAndRunUpdateJobs(currentDocuments); -} - -static void addUpdateAnnotationsJobsAndProcess(DocumentProcessor &processor) -{ - processor.addJob(JobRequest::Type::UpdateAnnotations, - PreferredTranslationUnit::PreviouslyParsed); - processor.addJob(JobRequest::Type::UpdateExtraAnnotations, - PreferredTranslationUnit::RecentlyParsed); - processor.process(); -} - -void ClangCodeModelServer::addAndRunUpdateJobs(std::vector<Document> documents) -{ - for (auto &document : documents) { - DocumentProcessor processor = documentProcessors().processor(document); - - // Run the regular edit-reparse-job - addUpdateAnnotationsJobsAndProcess(processor); - - // If requested, run jobs to increase the responsiveness of the document - if (useSupportiveTranslationUnit() && document.isResponsivenessIncreaseNeeded()) { - QTC_CHECK(!document.isResponsivenessIncreased()); - QTC_CHECK(!processor.hasSupportiveTranslationUnit()); - document.setResponsivenessIncreaseNeeded(false); - processor.startInitializingSupportiveTranslationUnit(); - } - } -} - -void ClangCodeModelServer::processTimerForVisibleButNotCurrentDocuments() -{ - if (documents.dirtyAndVisibleButNotCurrentDocuments().empty()) { - updateVisibleButNotCurrentDocumentsTimer.stop(); - } else { - updateVisibleButNotCurrentDocumentsTimer.start( - updateVisibleButNotCurrentDocumentsTimeOutInMs); - } -} - -void ClangCodeModelServer::processSuspendResumeJobs(const std::vector<Document> &documents) -{ - const SuspendResumeJobs suspendResumeJobs = createSuspendResumeJobs(documents); - for (const SuspendResumeJobsEntry &entry : suspendResumeJobs) { - DocumentProcessor processor = documentProcessors().processor(entry.document); - processor.addJob(entry.jobRequestType, entry.preferredTranslationUnit); - if (entry.jobRequestType == JobRequest::Type::ResumeDocument) { - processor.addJob(JobRequest::Type::UpdateExtraAnnotations, - PreferredTranslationUnit::RecentlyParsed); - } - processor.process(); - } -} - -bool ClangCodeModelServer::onJobFinished(const Jobs::RunningJob &jobRecord, IAsyncJob *job) -{ - if (jobRecord.jobRequest.type == JobRequest::Type::UpdateAnnotations) { - const auto updateJob = static_cast<UpdateAnnotationsJob *>(job); - return resetDocumentsWithUnresolvedIncludes({updateJob->pinnedDocument()}); - } - - return false; -} - -void ClangCodeModelServer::categorizeFileContainers(const QVector<FileContainer> &fileContainers, - QVector<FileContainer> &toCreate, - DocumentResetInfos &toReset) const -{ - for (const FileContainer &fileContainer : fileContainers) { - const std::vector<Document> matching = documents.filtered([&](const Document &document) { - return document.filePath() == fileContainer.filePath; - }); - if (matching.empty()) - toCreate.push_back(fileContainer); - else - toReset.push_back(DocumentResetInfo{*matching.begin(), fileContainer}); - } -} - -std::vector<Document> ClangCodeModelServer::resetDocuments(const DocumentResetInfos &infos) -{ - std::vector<Document> newDocuments; - - for (const DocumentResetInfo &info : infos) { - const Document &document = info.documentToRemove; - QTC_CHECK(document.filePath() == info.fileContainer.filePath); - - documents.remove({document.fileContainer()}); - - Document newDocument = *documents.create({info.fileContainer}).begin(); - newDocument.setDirtyIfDependencyIsMet(document.filePath()); - newDocument.setIsUsedByCurrentEditor(document.isUsedByCurrentEditor()); - newDocument.setIsVisibleInEditor(document.isVisibleInEditor(), document.visibleTimePoint()); - newDocument.setResponsivenessIncreaseNeeded(document.isResponsivenessIncreased()); - - documentProcessors().reset(document, newDocument); - - newDocuments.push_back(newDocument); - } - - return newDocuments; -} - -static bool isDocumentWithUnresolvedIncludesFixable(const Document &document, - const UnsavedFiles &unsavedFiles) -{ - for (uint i = 0; i < unsavedFiles.count(); ++i) { - const UnsavedFile &unsavedFile = unsavedFiles.at(i); - const Utf8String unsavedFilePath = QDir::cleanPath(unsavedFile.filePath()); - - for (const Utf8String &unresolvedPath : document.unresolvedFilePaths()) { - const QString documentDir = QFileInfo(document.filePath()).absolutePath(); - const QString candidate = QDir::cleanPath(documentDir + "/" + unresolvedPath.toString()); - - if (Utf8String(candidate) == unsavedFilePath) - return true; - - for (const Utf8String &headerPath : document.headerPaths()) { - Utf8String candidate = headerPath; - candidate.append(QStringLiteral("/")); - candidate.append(unresolvedPath); - candidate = QDir::cleanPath(candidate); - if (candidate == unsavedFilePath) - return true; - } - } - } - - return false; -} - -int ClangCodeModelServer::resetDocumentsWithUnresolvedIncludes( - const std::vector<Document> &documents) -{ - DocumentResetInfos toReset; - - for (const Document &document : documents) { - if (document.unresolvedFilePaths().isEmpty()) - continue; - if (isDocumentWithUnresolvedIncludesFixable(document, unsavedFiles)) - toReset << DocumentResetInfo{document, document.fileContainer()}; - } - - resetDocuments(toReset); - - return toReset.size(); -} - -void ClangCodeModelServer::setUpdateAnnotationsTimeOutInMsForTestsOnly(int value) -{ - updateAnnotationsTimeOutInMs = value; -} - -void ClangCodeModelServer::setUpdateVisibleButNotCurrentDocumentsTimeOutInMsForTestsOnly(int value) -{ - updateVisibleButNotCurrentDocumentsTimeOutInMs = value; -} - -DocumentProcessors &ClangCodeModelServer::documentProcessors() -{ - if (!documentProcessors_) { - // DocumentProcessors needs a reference to the client, but the client - // is not known at construction time of ClangCodeModelServer, so - // construct DocumentProcessors in a lazy manner. - documentProcessors_.reset(new DocumentProcessors(documents, unsavedFiles, *client())); - } - - return *documentProcessors_.data(); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangcodemodelserver.h b/src/tools/clangbackend/source/clangcodemodelserver.h deleted file mode 100644 index 471c27bd8d..0000000000 --- a/src/tools/clangbackend/source/clangcodemodelserver.h +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocument.h" -#include "clangdocuments.h" -#include "clangdocumentprocessors.h" -#include "clangjobrequest.h" -#include "unsavedfiles.h" - -#include <clangcodemodelserverinterface.h> -#include <ipcclientprovider.h> -#include <utf8string.h> - -#include <QScopedPointer> -#include <QTimer> - -namespace ClangBackEnd { - -struct DocumentResetInfo { - Document documentToRemove; - FileContainer fileContainer; -}; -using DocumentResetInfos = QVector<DocumentResetInfo>; - -class ClangCodeModelServer : public ClangCodeModelServerInterface, - public IpcClientProvider<ClangCodeModelClientInterface> -{ -public: - ClangCodeModelServer(); - - void end() override; - - void documentsOpened(const DocumentsOpenedMessage &message) override; - void documentsChanged(const DocumentsChangedMessage &message) override; - void documentsClosed(const DocumentsClosedMessage &message) override; - void documentVisibilityChanged(const DocumentVisibilityChangedMessage &message) override; - - void unsavedFilesUpdated(const UnsavedFilesUpdatedMessage &message) override; - void unsavedFilesRemoved(const UnsavedFilesRemovedMessage &message) override; - - void requestCompletions(const RequestCompletionsMessage &message) override; - void requestAnnotations(const RequestAnnotationsMessage &message) override; - void requestReferences(const RequestReferencesMessage &message) override; - void requestFollowSymbol(const RequestFollowSymbolMessage &message) override; - void requestToolTip(const RequestToolTipMessage &message) override; - -public: // for tests - const Documents &documentsForTestOnly() const; - QList<Jobs::RunningJob> runningJobsForTestsOnly(); - int queueSizeForTestsOnly(); - bool isTimerRunningForTestOnly() const; - void setUpdateAnnotationsTimeOutInMsForTestsOnly(int value); - void setUpdateVisibleButNotCurrentDocumentsTimeOutInMsForTestsOnly(int value); - DocumentProcessors &documentProcessors(); - -private: - void processJobsForVisibleDocuments(); - void processJobsForCurrentDocument(); - void processTimerForVisibleButNotCurrentDocuments(); - void processSuspendResumeJobs(const std::vector<Document> &documents); - - bool onJobFinished(const Jobs::RunningJob &jobRecord, IAsyncJob *job); - - void categorizeFileContainers(const QVector<FileContainer> &fileContainers, - QVector<FileContainer> &toCreate, - DocumentResetInfos &toReset) const; - std::vector<Document> resetDocuments(const DocumentResetInfos &infos); - int resetDocumentsWithUnresolvedIncludes(const std::vector<Document> &documents); - - void addAndRunUpdateJobs(std::vector<Document> documents); - -private: - UnsavedFiles unsavedFiles; - Documents documents; - - QScopedPointer<DocumentProcessors> documentProcessors_; // Delayed initialization - - QTimer updateAnnotationsTimer; - int updateAnnotationsTimeOutInMs = 1500; - - QTimer updateVisibleButNotCurrentDocumentsTimer; - int updateVisibleButNotCurrentDocumentsTimeOutInMs = 2000; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangcompletecodejob.cpp b/src/tools/clangbackend/source/clangcompletecodejob.cpp deleted file mode 100644 index ad033a9ea5..0000000000 --- a/src/tools/clangbackend/source/clangcompletecodejob.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangcompletecodejob.h" - -#include <clangsupport/clangsupportdebugutils.h> -#include <clangsupport/clangcodemodelclientinterface.h> -#include <clangsupport/completionsmessage.h> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -IAsyncJob::AsyncPrepareResult CompleteCodeJob::prepareAsyncRun() -{ - const JobRequest jobRequest = context().jobRequest; - QTC_ASSERT(jobRequest.type == JobRequest::Type::RequestCompletions, return AsyncPrepareResult()); - QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); - - const TranslationUnit translationUnit = *m_translationUnit; - const UnsavedFiles unsavedFiles = *context().unsavedFiles; - const quint32 line = jobRequest.line; - const quint32 column = jobRequest.column; - const qint32 funcNameStartLine = jobRequest.funcNameStartLine; - const qint32 funcNameStartColumn = jobRequest.funcNameStartColumn; - setRunner([translationUnit, unsavedFiles, line, column, - funcNameStartLine, funcNameStartColumn]() { - TIME_SCOPE_DURATION("CompleteCodeJobRunner"); - - UnsavedFiles theUnsavedFiles = unsavedFiles; - CompleteCodeJob::AsyncResult asyncResult; - asyncResult = translationUnit.complete(theUnsavedFiles, line, column, - funcNameStartLine, funcNameStartColumn); - - return asyncResult; - }); - - return AsyncPrepareResult{translationUnit.id()}; -} - -void CompleteCodeJob::finalizeAsyncRun() -{ - if (context().isDocumentOpen()) { - const AsyncResult result = asyncResult(); - - const CompletionsMessage message(result, context().jobRequest.ticketNumber); - context().client->completions(message); - } -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangcompletecodejob.h b/src/tools/clangbackend/source/clangcompletecodejob.h deleted file mode 100644 index 0d62ce8b94..0000000000 --- a/src/tools/clangbackend/source/clangcompletecodejob.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocumentjob.h" - -#include <clangsupport/codecompletion.h> - -namespace ClangBackEnd { - -class CompleteCodeJob : public DocumentJob<CodeCompletions> -{ -public: - using AsyncResult = CodeCompletions; - - AsyncPrepareResult prepareAsyncRun() override; - void finalizeAsyncRun() override; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocument.cpp b/src/tools/clangbackend/source/clangdocument.cpp deleted file mode 100644 index 672c902854..0000000000 --- a/src/tools/clangbackend/source/clangdocument.cpp +++ /dev/null @@ -1,453 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangdocument.h" - -#include "clangdocuments.h" -#include "clangstring.h" -#include "clangunsavedfilesshallowarguments.h" -#include "codecompleter.h" -#include "clangexceptions.h" -#include "clangtranslationunit.h" -#include "clangtranslationunits.h" -#include "clangtranslationunitupdater.h" -#include "unsavedfiles.h" -#include "unsavedfile.h" - -#include <utf8string.h> - -#include <QDebug> -#include <QFileInfo> -#include <QLoggingCategory> - -#include <ostream> - -namespace ClangBackEnd { - -class DocumentData -{ -public: - DocumentData(const Utf8String &filePath, - const Utf8StringVector &compilationArguments, - const Utf8StringVector &headerPaths, - Documents &documents); - ~DocumentData(); - -public: - Documents &documents; - - const Utf8String filePath; - const Utf8StringVector compilationArguments; - const Utf8StringVector headerPaths; - - TranslationUnits translationUnits; - - QSet<Utf8String> dependedFilePaths; - QSet<Utf8String> unresolvedFilePaths; - - uint documentRevision = 0; - - TimePoint visibleTimePoint; - - TimePoint isDirtyChangeTimePoint; - bool isDirty = false; - - bool hasParseOrReparseFailed = false; - bool isUsedByCurrentEditor = false; - bool isVisibleInEditor = false; - bool increaseResponsiveness = false; - bool isSuspended = false; -}; - -DocumentData::DocumentData(const Utf8String &filePath, - const Utf8StringVector &compilationArguments, - const Utf8StringVector &headerPaths, - Documents &documents) - : documents(documents), - filePath(filePath), - compilationArguments(compilationArguments), - headerPaths(headerPaths), - translationUnits(filePath), - isDirtyChangeTimePoint(Clock::now()) -{ - dependedFilePaths.insert(filePath); - translationUnits.createAndAppend(); -} - -DocumentData::~DocumentData() -{ -} - -Document::Document(const Utf8String &filePath, - const Utf8StringVector &compilationArguments, - const Utf8StringVector &headerPaths, - Documents &documents, - FileExistsCheck fileExistsCheck) - : d(std::make_shared<DocumentData>(filePath, - compilationArguments, - headerPaths, - documents)) -{ - if (fileExistsCheck == FileExistsCheck::Check) - checkIfFileExists(); -} - -Document::~Document() = default; -Document::Document(const Document &) = default; -Document &Document::operator=(const Document &) = default; - -Document::Document(Document &&other) - : d(std::move(other.d)) -{ -} - -Document &Document::operator=(Document &&other) -{ - d = std::move(other.d); - - return *this; -} - -void Document::reset() -{ - d.reset(); -} - -bool Document::isNull() const -{ - return !d; -} - -bool Document::isIntact() const -{ - return !isNull() - && fileExists() - && !d->hasParseOrReparseFailed; -} - -bool Document::isParsed() const -{ - return d->translationUnits.areAllTranslationUnitsParsed(); -} - -long Document::useCount() const -{ - return d.use_count(); -} - -Utf8String Document::filePath() const -{ - checkIfNull(); - - return d->filePath; -} - -Utf8StringVector Document::compilationArguments() const -{ - checkIfNull(); - - return d->compilationArguments; -} - -Utf8StringVector Document::headerPaths() const -{ - checkIfNull(); - - return d->headerPaths; -} - -FileContainer Document::fileContainer() const -{ - checkIfNull(); - - return FileContainer(d->filePath, - d->compilationArguments, - d->headerPaths, - Utf8String(), - false, - d->documentRevision); -} - -uint Document::documentRevision() const -{ - checkIfNull(); - - return d->documentRevision; -} - -void Document::setDocumentRevision(uint revision) -{ - checkIfNull(); - - d->documentRevision = revision; -} - -bool Document::isResponsivenessIncreased() const -{ - return d->translationUnits.size() > 1; -} - -bool Document::isResponsivenessIncreaseNeeded() const -{ - checkIfNull(); - - return d->increaseResponsiveness; -} - -void Document::setResponsivenessIncreaseNeeded(bool responsivenessIncreaseNeeded) -{ - d->increaseResponsiveness = responsivenessIncreaseNeeded; -} - -bool Document::isSuspended() const -{ - checkIfNull(); - - return d->isSuspended; -} - -void Document::setIsSuspended(bool isSuspended) -{ - checkIfNull(); - - d->isSuspended = isSuspended; -} - -bool Document::isUsedByCurrentEditor() const -{ - checkIfNull(); - - return d->isUsedByCurrentEditor; -} - -void Document::setIsUsedByCurrentEditor(bool isUsedByCurrentEditor) -{ - checkIfNull(); - - d->isUsedByCurrentEditor = isUsedByCurrentEditor; -} - -bool Document::isVisibleInEditor() const -{ - checkIfNull(); - - return d->isVisibleInEditor; -} - -void Document::setIsVisibleInEditor(bool isVisibleInEditor, const TimePoint &timePoint) -{ - checkIfNull(); - - if (isVisibleInEditor) - d->visibleTimePoint = timePoint; - d->isVisibleInEditor = isVisibleInEditor; -} - -TimePoint Document::visibleTimePoint() const -{ - checkIfNull(); - - return d->visibleTimePoint;; -} - -bool Document::isDirty() const -{ - checkIfNull(); - - return d->isDirty; -} - -TimePoint Document::isDirtyTimeChangePoint() const -{ - checkIfNull(); - - return d->isDirtyChangeTimePoint; -} - -void Document::setDirtyIfDependencyIsMet(const Utf8String &filePath) -{ - if (d->dependedFilePaths.contains(filePath) && isMainFileAndExistsOrIsOtherFile(filePath)) - setDirty(); -} - -TranslationUnitUpdateInput Document::createUpdateInput() const -{ - TranslationUnitUpdateInput updateInput; - updateInput.reparseNeeded = d->isDirty; - updateInput.needsToBeReparsedChangeTimePoint = d->isDirtyChangeTimePoint; - updateInput.filePath = d->filePath; - updateInput.compilationArguments = d->compilationArguments; - updateInput.unsavedFiles = d->documents.unsavedFiles(); - - return updateInput; -} - -TranslationUnitUpdater Document::createUpdater() const -{ - TranslationUnit unit = translationUnit(); - - const TranslationUnitUpdateInput updateInput = createUpdateInput(); - TranslationUnitUpdater updater(unit.id(), - unit.cxIndex(), - unit.cxTranslationUnit(), - updateInput); - - return updater; -} - -void Document::setHasParseOrReparseFailed(bool hasFailed) -{ - d->hasParseOrReparseFailed = hasFailed; -} - -void Document::incorporateUpdaterResult(const TranslationUnitUpdateResult &result) const -{ - d->hasParseOrReparseFailed = result.hasParseOrReparseFailed; - if (d->hasParseOrReparseFailed) { - d->isDirty = false; - return; - } - - if (result.hasParsed() || result.hasReparsed()) { - d->dependedFilePaths = result.dependedOnFilePaths; - - const TimePoint timePoint = qMax(result.parseTimePoint, result.reparseTimePoint); - d->translationUnits.updateParseTimePoint(result.translationUnitId, timePoint); - } - - d->documents.addWatchedFiles(d->dependedFilePaths); - - if (result.hasReparsed() - && result.needsToBeReparsedChangeTimePoint == d->isDirtyChangeTimePoint) { - d->isDirty = false; - } -} - -const QSet<Utf8String> Document::unresolvedFilePaths() const -{ - checkIfNull(); - - return d->unresolvedFilePaths; -} - -void Document::setUnresolvedFilePaths(const QSet<Utf8String> &unresolved) -{ - checkIfNull(); - - d->unresolvedFilePaths = unresolved; -} - -TranslationUnit Document::translationUnit(PreferredTranslationUnit preferredTranslationUnit) const -{ - checkIfNull(); - - return d->translationUnits.get(preferredTranslationUnit); -} - -TranslationUnits &Document::translationUnits() const -{ - return d->translationUnits; -} - -void Document::parse() const -{ - checkIfNull(); - - const TranslationUnitUpdateInput updateInput = createUpdateInput(); - TranslationUnitUpdateResult result = translationUnit().parse(updateInput); - - incorporateUpdaterResult(result); -} - -void Document::reparse() const -{ - checkIfNull(); - - const TranslationUnitUpdateInput updateInput = createUpdateInput(); - TranslationUnitUpdateResult result = translationUnit().reparse(updateInput); - - incorporateUpdaterResult(result); -} - -const QSet<Utf8String> Document::dependedFilePaths() const -{ - checkIfNull(); - checkIfFileExists(); - - return d->dependedFilePaths; -} - -void Document::setDependedFilePaths(const QSet<Utf8String> &filePaths) -{ - d->dependedFilePaths = filePaths; -} - -void Document::setDirty() -{ - d->isDirtyChangeTimePoint = Clock::now(); - d->isDirty = true; -} - -void Document::checkIfNull() const -{ - if (isNull()) - throw DocumentIsNullException(); -} - -void Document::checkIfFileExists() const -{ - if (!fileExists()) - throw DocumentFileDoesNotExistException(d->filePath); -} - -bool Document::fileExists() const -{ - return QFileInfo::exists(d->filePath.toString()); -} - -bool Document::isMainFileAndExistsOrIsOtherFile(const Utf8String &filePath) const -{ - if (filePath == d->filePath) - return QFileInfo::exists(d->filePath); - - return true; -} - -bool operator==(const Document &first, const Document &second) -{ - return first.filePath() == second.filePath(); -} - -std::ostream &operator<<(std::ostream &os, const Document &document) -{ - os << "(" - << document.filePath() << ", " - << document.documentRevision() - << ")"; - - return os; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocument.h b/src/tools/clangbackend/source/clangdocument.h deleted file mode 100644 index a637731a6e..0000000000 --- a/src/tools/clangbackend/source/clangdocument.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangtranslationunitupdater.h" - -#include "clangbackend_global.h" -#include "clangtranslationunit.h" - -#include <utf8stringvector.h> - -#include <clang-c/Index.h> - -#include <QSet> -#include <QtGlobal> - -#include <memory> - -class Utf8String; - -namespace ClangBackEnd { - -class TranslationUnit; -class TranslationUnits; -class DocumentData; -class TranslationUnitUpdateResult; -class FileContainer; -class Documents; - -class Document -{ -public: - enum class FileExistsCheck { - Check, - DoNotCheck - }; - - Document() = default; - Document(const Utf8String &filePath, - const Utf8StringVector &compilationArguments, - const Utf8StringVector &headerPaths, - Documents &documents, - FileExistsCheck fileExistsCheck = FileExistsCheck::Check); - ~Document(); - - Document(const Document &document); - Document &operator=(const Document &document); - - Document(Document &&document); - Document &operator=(Document &&document); - - void reset(); - - bool isNull() const; - bool isIntact() const; - bool isParsed() const; - long useCount() const; - - Utf8String filePath() const; - Utf8StringVector compilationArguments() const; - Utf8StringVector headerPaths() const; - FileContainer fileContainer() const; - - uint documentRevision() const; - void setDocumentRevision(uint revision); - - bool isResponsivenessIncreased() const; - bool isResponsivenessIncreaseNeeded() const; - void setResponsivenessIncreaseNeeded(bool responsivenessIncreaseNeeded); - - bool isSuspended() const; - void setIsSuspended(bool isSuspended); - - bool isUsedByCurrentEditor() const; - void setIsUsedByCurrentEditor(bool isUsedByCurrentEditor); - - bool isVisibleInEditor() const; - void setIsVisibleInEditor(bool isVisibleInEditor, const TimePoint &timePoint); - TimePoint visibleTimePoint() const; - - bool isDirty() const; - TimePoint isDirtyTimeChangePoint() const; - void setDirtyIfDependencyIsMet(const Utf8String &filePath); - - TranslationUnitUpdateInput createUpdateInput() const; - void incorporateUpdaterResult(const TranslationUnitUpdateResult &result) const; - - const QSet<Utf8String> unresolvedFilePaths() const; - void setUnresolvedFilePaths(const QSet<Utf8String> &unresolved); - - TranslationUnit translationUnit(PreferredTranslationUnit preferredTranslationUnit - = PreferredTranslationUnit::RecentlyParsed) const; - TranslationUnits &translationUnits() const; - - friend bool operator==(const Document &first, const Document &second); - friend std::ostream &operator<<(std::ostream &os, const Document &document); - -public: // for tests - void parse() const; - void reparse() const; - const QSet<Utf8String> dependedFilePaths() const; - void setDependedFilePaths(const QSet<Utf8String> &filePaths); - TranslationUnitUpdater createUpdater() const; - void setHasParseOrReparseFailed(bool hasFailed); - -private: - void setDirty(); - - void checkIfNull() const; - void checkIfFileExists() const; - - bool fileExists() const; - bool isMainFileAndExistsOrIsOtherFile(const Utf8String &filePath) const; - -private: - mutable std::shared_ptr<DocumentData> d; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocumentjob.h b/src/tools/clangbackend/source/clangdocumentjob.h deleted file mode 100644 index d9b71d3a43..0000000000 --- a/src/tools/clangbackend/source/clangdocumentjob.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangasyncjob.h" -#include "clangdocument.h" - -#include <clangsupport/filecontainer.h> - -#include <memory> - -namespace ClangBackEnd { - -template<class Result> -class DocumentJob : public AsyncJob<Result> -{ -public: - Document pinnedDocument() const { return m_pinnedDocument; } - -protected: - bool acquireDocument() - { - try { - m_pinnedDocument = IAsyncJob::context().documentForJobRequest(); - m_pinnedFileContainer = m_pinnedDocument.fileContainer(); - - const PreferredTranslationUnit preferredTranslationUnit - = IAsyncJob::context().jobRequest.preferredTranslationUnit; - m_translationUnit.reset( - new TranslationUnit(m_pinnedDocument.translationUnit(preferredTranslationUnit))); - return true; - } catch (const std::exception &) { - return false; - } - } - -protected: - Document m_pinnedDocument; - FileContainer m_pinnedFileContainer; - - std::unique_ptr<TranslationUnit> m_translationUnit; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocumentprocessor.cpp b/src/tools/clangbackend/source/clangdocumentprocessor.cpp deleted file mode 100644 index dd390c6ba6..0000000000 --- a/src/tools/clangbackend/source/clangdocumentprocessor.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangdocumentprocessor.h" - -#include "clangdocuments.h" -#include "clangjobs.h" -#include "clangsupportivetranslationunitinitializer.h" - -#include "clangdocument.h" -#include "clangtranslationunits.h" - -#include <utils/algorithm.h> -#include <utils/qtcassert.h> - -#include <QFileInfo> - -namespace ClangBackEnd { - -class DocumentProcessorData -{ -public: - DocumentProcessorData(const Document &document, - Documents &documents, - UnsavedFiles &unsavedFiles, - ClangCodeModelClientInterface &client) - : document(document) - , documents(documents) - , jobs(documents, unsavedFiles, client, QFileInfo(document.filePath()).fileName()) - , supportiveTranslationUnitInitializer(document, jobs) - { - const auto isDocumentClosedChecker = [this](const Utf8String &filePath) { - return !this->documents.hasDocument(filePath); - }; - supportiveTranslationUnitInitializer.setIsDocumentClosedChecker(isDocumentClosedChecker); - } - -public: - Document document; - Documents &documents; - Jobs jobs; - - SupportiveTranslationUnitInitializer supportiveTranslationUnitInitializer; -}; - -DocumentProcessor::DocumentProcessor(const Document &document, - Documents &documents, - UnsavedFiles &unsavedFiles, - ClangCodeModelClientInterface &client) - : d(std::make_shared<DocumentProcessorData>(document, - documents, - unsavedFiles, - client)) -{ -} - -Jobs &DocumentProcessor::jobs() const -{ - return d->jobs; -} - -JobRequest DocumentProcessor::createJobRequest( - JobRequest::Type type, - PreferredTranslationUnit preferredTranslationUnit) const -{ - return d->jobs.createJobRequest(d->document, type, preferredTranslationUnit); -} - -void DocumentProcessor::addJob(const JobRequest &jobRequest) -{ - d->jobs.add(jobRequest); -} - -void DocumentProcessor::addJob(JobRequest::Type type, PreferredTranslationUnit preferredTranslationUnit) -{ - d->jobs.add(d->document, type, preferredTranslationUnit); -} - -JobRequests DocumentProcessor::process() -{ - return d->jobs.process(); -} - -JobRequests DocumentProcessor::stop() -{ - d->supportiveTranslationUnitInitializer.abort(); - return d->jobs.stop(); -} - -Document DocumentProcessor::document() const -{ - return d->document; -} - -bool DocumentProcessor::hasSupportiveTranslationUnit() const -{ - return d->supportiveTranslationUnitInitializer.state() - != SupportiveTranslationUnitInitializer::State::NotInitialized; -} - -void DocumentProcessor::startInitializingSupportiveTranslationUnit() -{ - d->supportiveTranslationUnitInitializer.startInitializing(); -} - -bool DocumentProcessor::isSupportiveTranslationUnitInitialized() const -{ - return d->supportiveTranslationUnitInitializer.state() - == SupportiveTranslationUnitInitializer::State::Initialized; -} - -JobRequests &DocumentProcessor::queue() -{ - return d->jobs.queue(); -} - -QList<Jobs::RunningJob> DocumentProcessor::runningJobs() const -{ - return d->jobs.runningJobs(); -} - -int DocumentProcessor::queueSize() const -{ - return d->jobs.queue().size(); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocumentprocessor.h b/src/tools/clangbackend/source/clangdocumentprocessor.h deleted file mode 100644 index 7de2664322..0000000000 --- a/src/tools/clangbackend/source/clangdocumentprocessor.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangjobrequest.h" -#include "clangjobs.h" - -#include <memory> - -namespace ClangBackEnd { - -class ClangCodeModelClientInterface; -class Document; -class Documents; -class DocumentProcessorData; -class JobRequest; -class UnsavedFiles; - -class DocumentProcessor -{ -public: - DocumentProcessor(const Document &document, - Documents &documents, - UnsavedFiles &unsavedFiles, - ClangCodeModelClientInterface &client); - - Jobs &jobs() const; - - JobRequest createJobRequest(JobRequest::Type type, - PreferredTranslationUnit preferredTranslationUnit - = PreferredTranslationUnit::RecentlyParsed) const; - - void addJob(const JobRequest &jobRequest); - void addJob(JobRequest::Type type, - PreferredTranslationUnit preferredTranslationUnit - = PreferredTranslationUnit::RecentlyParsed); - - JobRequests process(); - JobRequests stop(); - - Document document() const; - - bool hasSupportiveTranslationUnit() const; - void startInitializingSupportiveTranslationUnit(); - -public: // for tests - bool isSupportiveTranslationUnitInitialized() const; - JobRequests &queue(); - QList<Jobs::RunningJob> runningJobs() const; - int queueSize() const; - -private: - std::shared_ptr<DocumentProcessorData> d; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocumentprocessors.cpp b/src/tools/clangbackend/source/clangdocumentprocessors.cpp deleted file mode 100644 index 951e4ef7a1..0000000000 --- a/src/tools/clangbackend/source/clangdocumentprocessors.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangdocumentprocessors.h" -#include "clangdocument.h" -#include "clangexceptions.h" - -#include <utils/algorithm.h> - -namespace ClangBackEnd { - -DocumentProcessors::DocumentProcessors(Documents &documents, - UnsavedFiles &unsavedFiles, - ClangCodeModelClientInterface &client) - : m_documents(documents) - , m_unsavedFiles(unsavedFiles) - , m_client(client) -{ -} - -DocumentProcessor DocumentProcessors::create(const Document &document) -{ - const Utf8String filePath{document.filePath()}; - if (m_processors.contains(filePath)) - throw DocumentProcessorAlreadyExists(document.filePath()); - - const DocumentProcessor element(document, m_documents, m_unsavedFiles, m_client); - m_processors.insert(filePath, element); - - return element; -} - -DocumentProcessor DocumentProcessors::processor(const Document &document) -{ - const Utf8String filePath = document.filePath(); - const auto it = m_processors.find(filePath); - if (it == m_processors.end()) - throw DocumentProcessorDoesNotExist(filePath); - - return *it; -} - -QList<DocumentProcessor> DocumentProcessors::processors() const -{ - return m_processors.values(); -} - -void DocumentProcessors::remove(const Document &document) -{ - const int itemsRemoved = m_processors.remove(document.filePath()); - if (itemsRemoved != 1) - throw DocumentProcessorDoesNotExist(document.filePath()); -} - -void DocumentProcessors::reset(const Document &oldDocument, const Document &newDocument) -{ - // Wait until the currently running jobs finish and remember the not yet - // processed job requests for the new processor... - const JobRequests jobsStillInQueue = processor(oldDocument).stop(); - // ...but do not take over irrelevant ones. - const JobRequests jobsForNewProcessor = Utils::filtered(jobsStillInQueue, - [](const JobRequest &job) { - return job.isTakeOverable(); - }); - const Jobs::JobFinishedCallback jobFinishedCallback - = processor(oldDocument).jobs().jobFinishedCallback(); - - // Remove current processor - remove(oldDocument); - - // Create new processor and take over not yet processed jobs. - DocumentProcessor newProcessor = create(newDocument); - for (const JobRequest &job : jobsForNewProcessor) - newProcessor.addJob(job); - newProcessor.jobs().setJobFinishedCallback(jobFinishedCallback); -} - -JobRequests DocumentProcessors::process() -{ - JobRequests jobsStarted; - for (auto &processor : m_processors) - jobsStarted += processor.process(); - - return jobsStarted; -} - -QList<Jobs::RunningJob> DocumentProcessors::runningJobs() const -{ - QList<Jobs::RunningJob> jobs; - for (auto &processor : m_processors) - jobs += processor.runningJobs(); - - return jobs; -} - -int DocumentProcessors::queueSize() const -{ - int total = 0; - for (auto &processor : m_processors) - total += processor.queueSize(); - - return total; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocumentprocessors.h b/src/tools/clangbackend/source/clangdocumentprocessors.h deleted file mode 100644 index ab00fa8d56..0000000000 --- a/src/tools/clangbackend/source/clangdocumentprocessors.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocumentprocessor.h" -#include "clangjobs.h" - -#include <utf8string.h> - -#include <QMap> - -namespace ClangBackEnd { - -class Document; -class DocumentProcessor; - -class DocumentProcessors -{ -public: - DocumentProcessors(Documents &documents, - UnsavedFiles &unsavedFiles, - ClangCodeModelClientInterface &client); - - DocumentProcessor create(const Document &document); - DocumentProcessor processor(const Document &document); - void remove(const Document &document); - void reset(const Document &oldDocument, const Document &newDocument); - - JobRequests process(); - -public: // for tests - QList<DocumentProcessor> processors() const; - QList<Jobs::RunningJob> runningJobs() const; - int queueSize() const; - -private: - Documents &m_documents; - UnsavedFiles &m_unsavedFiles; - ClangCodeModelClientInterface &m_client; - - QMap<Utf8String, DocumentProcessor> m_processors; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocuments.cpp b/src/tools/clangbackend/source/clangdocuments.cpp deleted file mode 100644 index 7b274d7755..0000000000 --- a/src/tools/clangbackend/source/clangdocuments.cpp +++ /dev/null @@ -1,291 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangdocuments.h" - -#include <diagnosticset.h> -#include <tokenprocessor.h> -#include <clangexceptions.h> -#include <skippedsourceranges.h> -#include <unsavedfiles.h> - -#include <utils/algorithm.h> - -#include <QDebug> - -#include <algorithm> - -namespace ClangBackEnd { - -bool operator==(const FileContainer &fileContainer, const Document &document) -{ - return fileContainer.filePath == document.filePath(); -} - -bool operator==(const Document &document, const FileContainer &fileContainer) -{ - return fileContainer == document; -} - -Documents::Documents(UnsavedFiles &unsavedFiles) - : fileSystemWatcher(*this), - unsavedFiles_(unsavedFiles) -{ -} - -std::vector<Document> Documents::create(const QVector<FileContainer> &fileContainers) -{ - checkIfDocumentsDoNotExist(fileContainers); - - std::vector<Document> createdDocuments; - - for (const FileContainer &fileContainer : fileContainers) { - if (fileContainer.hasUnsavedFileContent) - updateDocumentsWithChangedDependency(fileContainer.filePath); - - createdDocuments.push_back(createDocument(fileContainer)); - } - - return createdDocuments; -} - -std::vector<Document> Documents::update(const QVector<FileContainer> &fileContainers) -{ - checkIfDocumentsForFilePathsExist(fileContainers); - - std::vector<Document> createdDocuments; - - for (const FileContainer &fileContainer : fileContainers) { - const std::vector<Document> documents = updateDocument(fileContainer); - createdDocuments.insert(createdDocuments.end(), documents.begin(), documents.end()); - - updateDocumentsWithChangedDependency(fileContainer.filePath); - } - - return createdDocuments; -} - -static bool removeFromFileContainer(QVector<FileContainer> &fileContainers, const Document &document) -{ - auto position = std::remove(fileContainers.begin(), fileContainers.end(), document); - - bool entryIsRemoved = position != fileContainers.end(); - - fileContainers.erase(position, fileContainers.end()); - - return entryIsRemoved; -} - -void Documents::remove(const QVector<FileContainer> &fileContainers) -{ - removeDocuments(fileContainers); - updateDocumentsWithChangedDependencies(fileContainers); -} - -void Documents::setUsedByCurrentEditor(const Utf8String &filePath) -{ - for (Document &document : documents_) - document.setIsUsedByCurrentEditor(document.filePath() == filePath); -} - -void Documents::setVisibleInEditors(const Utf8StringVector &filePaths) -{ - const TimePoint timePoint = Clock::now(); - for (Document &document : documents_) - document.setIsVisibleInEditor(filePaths.contains(document.filePath()), timePoint); -} - -const Document &Documents::document(const Utf8String &filePath) const -{ - auto findIterator = findDocument(filePath); - - if (findIterator == documents_.end()) - throw DocumentDoesNotExistException(filePath); - - return *findIterator; -} - -const Document &Documents::document(const FileContainer &fileContainer) const -{ - return document(fileContainer.filePath); -} - -const std::vector<Document> &Documents::documents() const -{ - return documents_; -} - -const std::vector<Document> Documents::filtered(const IsMatchingDocument &isMatchingDocument) const -{ - return Utils::filtered(documents_, isMatchingDocument); -} - -std::vector<Document> Documents::dirtyAndVisibleButNotCurrentDocuments() const -{ - return filtered([](const Document &document) { - return document.isDirty() - && document.isVisibleInEditor() - && !document.isUsedByCurrentEditor(); - }); -} - -UnsavedFiles Documents::unsavedFiles() const -{ - return unsavedFiles_; -} - -void Documents::addWatchedFiles(QSet<Utf8String> &filePaths) -{ - fileSystemWatcher.addFiles(filePaths); -} - -void Documents::updateDocumentsWithChangedDependency(const Utf8String &filePath) -{ - for (auto &document : documents_) - document.setDirtyIfDependencyIsMet(filePath); -} - -void Documents::updateDocumentsWithChangedDependencies(const QVector<FileContainer> &fileContainers) -{ - for (const FileContainer &fileContainer : fileContainers) - updateDocumentsWithChangedDependency(fileContainer.filePath); -} - -QVector<FileContainer> Documents::newerFileContainers(const QVector<FileContainer> &fileContainers) const -{ - QVector<FileContainer> newerContainers; - - auto documentIsNewer = [this] (const FileContainer &fileContainer) { - try { - return document(fileContainer).documentRevision() != fileContainer.documentRevision; - } catch (const DocumentDoesNotExistException &) { - return true; - } - }; - - std::copy_if(fileContainers.cbegin(), - fileContainers.cend(), - std::back_inserter(newerContainers), - documentIsNewer); - - return newerContainers; -} - -const ClangFileSystemWatcher *Documents::clangFileSystemWatcher() const -{ - return &fileSystemWatcher; -} - -Document Documents::createDocument(const FileContainer &fileContainer) -{ - const Document::FileExistsCheck checkIfFileExists = fileContainer.hasUnsavedFileContent - ? Document::FileExistsCheck::DoNotCheck - : Document::FileExistsCheck::Check; - - documents_.emplace_back(fileContainer.filePath, - fileContainer.compilationArguments, - fileContainer.headerPaths, - *this, - checkIfFileExists); - - documents_.back().setDocumentRevision(fileContainer.documentRevision); - - return documents_.back(); -} - -std::vector<Document> Documents::updateDocument(const FileContainer &fileContainer) -{ - const auto documents = findAllDocumentsWithFilePath(fileContainer.filePath); - - for (auto document : documents) - document.setDocumentRevision(fileContainer.documentRevision); - - return documents; -} - -std::vector<Document>::const_iterator Documents::findDocument(const FileContainer &fileContainer) const -{ - return std::find(documents_.begin(), documents_.end(), fileContainer); -} - -std::vector<Document> Documents::findAllDocumentsWithFilePath(const Utf8String &filePath) -{ - const auto filePathCompare = [&filePath] (const Document &document) { - return document.filePath() == filePath; - }; - - std::vector<Document> documents; - std::copy_if(documents_.begin(), - documents_.end(), - std::back_inserter(documents), - filePathCompare); - - return documents; -} - -bool Documents::hasDocument(const Utf8String &filePath) const -{ - auto filePathCompare = [&filePath] (const Document &document) { - return document.filePath() == filePath; - }; - - auto findIterator = std::find_if(documents_.begin(), documents_.end(), filePathCompare); - - return findIterator != documents_.end(); -} - -void Documents::checkIfDocumentsDoNotExist(const QVector<FileContainer> &fileContainers) const -{ - for (const FileContainer &fileContainer : fileContainers) { - if (hasDocument(fileContainer.filePath)) - throw DocumentAlreadyExistsException(fileContainer.filePath); - } -} - -void Documents::checkIfDocumentsForFilePathsExist(const QVector<FileContainer> &fileContainers) const -{ - for (const FileContainer &fileContainer : fileContainers) { - if (!hasDocument(fileContainer.filePath)) - throw DocumentDoesNotExistException(fileContainer.filePath); - } -} - -void Documents::removeDocuments(const QVector<FileContainer> &fileContainers) -{ - QVector<FileContainer> processedFileContainers = fileContainers; - - auto removeBeginIterator = std::remove_if(documents_.begin(), documents_.end(), [&processedFileContainers] (const Document &document) { - return removeFromFileContainer(processedFileContainers, document); - }); - - documents_.erase(removeBeginIterator, documents_.end()); - - if (!processedFileContainers.isEmpty()) { - const FileContainer fileContainer = processedFileContainers.first(); - throw DocumentDoesNotExistException(fileContainer.filePath); - } -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocuments.h b/src/tools/clangbackend/source/clangdocuments.h deleted file mode 100644 index 9523e67c83..0000000000 --- a/src/tools/clangbackend/source/clangdocuments.h +++ /dev/null @@ -1,90 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocument.h" -#include "clangfilesystemwatcher.h" - -#include <filecontainer.h> - -#include <QVector> - -#include <functional> -#include <vector> - -namespace ClangBackEnd { - -class UnsavedFiles; - -class Documents -{ -public: - Documents(UnsavedFiles &unsavedFiles); - - std::vector<Document> create(const QVector<FileContainer> &fileContainers); - std::vector<Document> update(const QVector<FileContainer> &fileContainers); - void remove(const QVector<FileContainer> &fileContainers); - - void setUsedByCurrentEditor(const Utf8String &filePath); - void setVisibleInEditors(const Utf8StringVector &filePaths); - - const Document &document(const Utf8String &filePath) const; - const Document &document(const FileContainer &fileContainer) const; - bool hasDocument(const Utf8String &filePath) const; - - const std::vector<Document> &documents() const; - using IsMatchingDocument = std::function<bool(const Document &document)>; - const std::vector<Document> filtered(const IsMatchingDocument &isMatchingDocument) const; - std::vector<Document> dirtyAndVisibleButNotCurrentDocuments() const; - - UnsavedFiles unsavedFiles() const; - - void addWatchedFiles(QSet<Utf8String> &filePaths); - - void updateDocumentsWithChangedDependency(const Utf8String &filePath); - void updateDocumentsWithChangedDependencies(const QVector<FileContainer> &fileContainers); - - QVector<FileContainer> newerFileContainers(const QVector<FileContainer> &fileContainers) const; - - const ClangFileSystemWatcher *clangFileSystemWatcher() const; - -private: - Document createDocument(const FileContainer &fileContainer); - std::vector<Document> updateDocument(const FileContainer &fileContainer); - std::vector<Document>::const_iterator findDocument(const FileContainer &fileContainer) const; - std::vector<Document> findAllDocumentsWithFilePath(const Utf8String &filePath); - void checkIfDocumentsDoNotExist(const QVector<FileContainer> &fileContainers) const; - void checkIfDocumentsForFilePathsExist(const QVector<FileContainer> &fileContainers) const; - - void removeDocuments(const QVector<FileContainer> &fileContainers); - -private: - ClangFileSystemWatcher fileSystemWatcher; - std::vector<Document> documents_; - UnsavedFiles &unsavedFiles_; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocumentsuspenderresumer.cpp b/src/tools/clangbackend/source/clangdocumentsuspenderresumer.cpp deleted file mode 100644 index 6be3aaa7c5..0000000000 --- a/src/tools/clangbackend/source/clangdocumentsuspenderresumer.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangdocumentsuspenderresumer.h" - -#include "clangsupport_global.h" -#include "clangdocumentprocessors.h" -#include "clangdocuments.h" - -#include <utils/algorithm.h> - -#include <algorithm> - -namespace ClangBackEnd { - -constexpr int DefaultHotDocumentsSize = 7; - -void categorizeHotColdDocuments(int hotDocumentsSize, - const std::vector<Document> &inDocuments, - std::vector<Document> &hotDocuments, - std::vector<Document> &coldDocuments) -{ - // Sort documents, most recently used/visible at top - std::vector<Document> documents = inDocuments; - std::stable_sort(documents.begin(), documents.end(), [](const Document &a, const Document &b) { - return a.visibleTimePoint() > b.visibleTimePoint(); - }); - - // Ensure that visible documents are always hot, otherwise not all visible - // documents will be resumed. - const auto isVisible = [](const Document &document) { return document.isVisibleInEditor(); }; - const int visibleDocumentsSize = Utils::count(documents, isVisible); - hotDocumentsSize = std::max(hotDocumentsSize, visibleDocumentsSize); - - if (documents.size() <= uint(hotDocumentsSize)) { - hotDocuments = documents; - coldDocuments.clear(); - } else { - const auto firstColdIterator = documents.begin() + hotDocumentsSize; - hotDocuments = std::vector<Document>(documents.begin(), firstColdIterator); - coldDocuments = std::vector<Document>(firstColdIterator, documents.end()); - } -} - -static int hotDocumentsSize() -{ - static int hotDocuments = -1; - if (hotDocuments == -1) { - bool ok = false; - const int fromEnvironment = qEnvironmentVariableIntValue("QTC_CLANG_HOT_DOCUMENTS", &ok); - hotDocuments = ok && fromEnvironment >= 1 ? fromEnvironment : DefaultHotDocumentsSize; - } - - return hotDocuments; -} - -static SuspendResumeJobs createJobs(const Document &document, JobRequest::Type type) -{ - SuspendResumeJobs jobs; - - jobs.append({document, type, PreferredTranslationUnit::RecentlyParsed}); - if (document.isResponsivenessIncreased()) - jobs.append({document, type, PreferredTranslationUnit::PreviouslyParsed}); - - return jobs; -} - -static bool isFineDocument(const Document &document) -{ - return !document.isNull() && document.isIntact(); -} - -static bool isSuspendable(const Document &document) -{ - return isFineDocument(document) - && !document.isSuspended() - && !document.isVisibleInEditor() - && document.isParsed(); -} - -static bool isResumable(const Document &document) -{ - return isFineDocument(document) - && document.isSuspended() - && document.isVisibleInEditor(); -} - -SuspendResumeJobs createSuspendResumeJobs(const std::vector<Document> &documents, - int customHotDocumentSize) -{ - SuspendResumeJobs jobs; - - std::vector<Document> hotDocuments; - std::vector<Document> coldDocuments; - - const int size = (customHotDocumentSize == -1) ? hotDocumentsSize() : customHotDocumentSize; - categorizeHotColdDocuments(size, documents, hotDocuments, coldDocuments); - - // Cold documents should be suspended... - const std::vector<Document> toSuspend = Utils::filtered(coldDocuments, &isSuspendable); - for (const Document &document : toSuspend) - jobs += createJobs(document, JobRequest::Type::SuspendDocument); - - // ...and hot documents that were suspended should be resumed - const std::vector<Document> toResume = Utils::filtered(hotDocuments, &isResumable); - for (const Document &document : toResume) - jobs += createJobs(document, JobRequest::Type::ResumeDocument); - - return jobs; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangdocumentsuspenderresumer.h b/src/tools/clangbackend/source/clangdocumentsuspenderresumer.h deleted file mode 100644 index 7e2bd8722d..0000000000 --- a/src/tools/clangbackend/source/clangdocumentsuspenderresumer.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocument.h" -#include "clangjobrequest.h" - -#include <vector> - -namespace ClangBackEnd { - -class SuspendResumeJobsEntry { -public: - SuspendResumeJobsEntry() = default; - SuspendResumeJobsEntry(const Document &document, - JobRequest::Type jobRequestType, - PreferredTranslationUnit preferredTranslationUnit) - : document(document) - , jobRequestType(jobRequestType) - , preferredTranslationUnit(preferredTranslationUnit) - { - } - - Document document; - JobRequest::Type jobRequestType = JobRequest::Type::SuspendDocument; - PreferredTranslationUnit preferredTranslationUnit = PreferredTranslationUnit::RecentlyParsed; -}; -using SuspendResumeJobs = QVector<SuspendResumeJobsEntry>; - -SuspendResumeJobs createSuspendResumeJobs(const std::vector<Document> &documents, - int customHotDocumentCounts = -1); - -// for tests -void categorizeHotColdDocuments(int hotDocumentsSize, - const std::vector<Document> &inDocuments, - std::vector<Document> &hotDocuments, - std::vector<Document> &coldDocuments); - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangexceptions.cpp b/src/tools/clangbackend/source/clangexceptions.cpp deleted file mode 100644 index b23304e6cb..0000000000 --- a/src/tools/clangbackend/source/clangexceptions.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangexceptions.h" - -namespace ClangBackEnd { - -const char *ClangBaseException::what() const noexcept -{ - return m_info.constData(); -} - -DocumentAlreadyExistsException::DocumentAlreadyExistsException(const Utf8String &filePath) -{ - m_info += Utf8StringLiteral("Document '") - + filePath - + Utf8StringLiteral("' already exists!"); -} - -DocumentDoesNotExistException::DocumentDoesNotExistException(const Utf8String &filePath) -{ - m_info += Utf8StringLiteral("Document '") - + filePath - + Utf8StringLiteral("' does not exist!"); -} - -DocumentFileDoesNotExistException::DocumentFileDoesNotExistException( - const Utf8String &filePath) -{ - m_info += Utf8StringLiteral("File ") - + filePath - + Utf8StringLiteral(" does not exist in file system!"); -} - -DocumentIsNullException::DocumentIsNullException() -{ - m_info = Utf8String::fromUtf8("Tried to access a null Document!"); -} - -DocumentProcessorAlreadyExists::DocumentProcessorAlreadyExists(const Utf8String &filePath) -{ - m_info = Utf8StringLiteral("Document processor for file '") - + filePath - + Utf8StringLiteral("' already exists!"); -} - -DocumentProcessorDoesNotExist::DocumentProcessorDoesNotExist(const Utf8String &filePath) -{ - m_info = Utf8StringLiteral("Document processor for file '") - + filePath - + Utf8StringLiteral("' does not exist!"); -} - -TranslationUnitDoesNotExist::TranslationUnitDoesNotExist(const Utf8String &filePath) -{ - m_info += Utf8StringLiteral("TranslationUnit for file '") - + filePath - + Utf8StringLiteral("' does not exist."); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangexceptions.h b/src/tools/clangbackend/source/clangexceptions.h deleted file mode 100644 index da94c96aef..0000000000 --- a/src/tools/clangbackend/source/clangexceptions.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <utf8stringvector.h> - -#include <clang-c/Index.h> - -#include <exception> - -namespace ClangBackEnd { - -class ClangBaseException : public std::exception -{ -public: - const char *what() const noexcept override; - -protected: - Utf8String m_info; -}; - -class DocumentAlreadyExistsException : public ClangBaseException -{ -public: - DocumentAlreadyExistsException(const Utf8String &filePath); -}; - -class DocumentDoesNotExistException : public ClangBaseException -{ -public: - DocumentDoesNotExistException(const Utf8String &filePath); -}; - -class DocumentFileDoesNotExistException : public ClangBaseException -{ -public: - DocumentFileDoesNotExistException(const Utf8String &filePath); -}; - -class DocumentIsNullException : public ClangBaseException -{ -public: - DocumentIsNullException(); -}; - -class DocumentProcessorAlreadyExists : public ClangBaseException -{ -public: - DocumentProcessorAlreadyExists(const Utf8String &filePath); -}; - -class DocumentProcessorDoesNotExist : public ClangBaseException -{ -public: - DocumentProcessorDoesNotExist(const Utf8String &filePath); -}; - -class TranslationUnitDoesNotExist : public ClangBaseException -{ -public: - TranslationUnitDoesNotExist(const Utf8String &filePath); -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangfilepath.cpp b/src/tools/clangbackend/source/clangfilepath.cpp deleted file mode 100644 index a5fc26b11d..0000000000 --- a/src/tools/clangbackend/source/clangfilepath.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangfilepath.h" - -#include <utf8string.h> - -#include <QByteArray> - -#if defined(Q_OS_WIN) -// Parameterized QDir::toNativeSeparators/-fromNativeSeparators for QByteArray -static inline QByteArray replace(const QByteArray &pathName, char toReplace, char replacement) -{ - int i = pathName.indexOf(toReplace); - if (i != -1) { - QByteArray n(pathName); - - char * const data = n.data(); - data[i++] = replacement; - - for (; i < n.length(); ++i) { - if (data[i] == toReplace) - data[i] = replacement; - } - - return n; - } - - return pathName; -} -#endif - -static QByteArray fromNativeSeparatorsForQByteArray(const QByteArray &pathName) -{ -#if defined(Q_OS_WIN) - return replace(pathName, '\\', '/'); -#else - return pathName; -#endif -} - -static QByteArray toNativeSeparatorsForQByteArray(const QByteArray &pathName) -{ -#if defined(Q_OS_WIN) - return replace(pathName, '/', '\\'); -#else - return pathName; -#endif -} - -namespace ClangBackEnd { - -Utf8String FilePath::fromNativeSeparators(const Utf8String &pathName) -{ - const QByteArray pathNameAsByteArray = pathName.toByteArray(); - - return Utf8String::fromUtf8(fromNativeSeparatorsForQByteArray(pathNameAsByteArray)); -} - -Utf8String FilePath::toNativeSeparators(const Utf8String &pathName) -{ - const QByteArray pathNameAsByteArray = pathName.toByteArray(); - - return Utf8String::fromUtf8(toNativeSeparatorsForQByteArray(pathNameAsByteArray)); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangfilepath.h b/src/tools/clangbackend/source/clangfilepath.h deleted file mode 100644 index 014c0129ed..0000000000 --- a/src/tools/clangbackend/source/clangfilepath.h +++ /dev/null @@ -1,38 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -class Utf8String; - -namespace ClangBackEnd { - -class FilePath { -public: - static Utf8String fromNativeSeparators(const Utf8String &pathName); - static Utf8String toNativeSeparators(const Utf8String &pathName); -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangfilesystemwatcher.cpp b/src/tools/clangbackend/source/clangfilesystemwatcher.cpp deleted file mode 100644 index bcd03fac61..0000000000 --- a/src/tools/clangbackend/source/clangfilesystemwatcher.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangfilesystemwatcher.h" - -#include "clangdocuments.h" - -#include <utf8stringvector.h> - -#include <QFileInfo> -#include <QStringList> - -#include <algorithm> -#include <iterator> - -namespace ClangBackEnd { - -namespace { -QStringList toStringList(const QSet<Utf8String> &files) -{ - QStringList resultList; - resultList.reserve(files.size()); - - std::copy(files.cbegin(), files.cend(), std::back_inserter(resultList)); - - return resultList; -} - -QStringList filterExistingFiles(QStringList &&filePaths) -{ - auto fileExists = [] (const QString &filePath) { - return QFileInfo::exists(filePath); - }; - - auto startOfNonExistingFilePaths = std::partition(filePaths.begin(), - filePaths.end(), - fileExists); - - filePaths.erase(startOfNonExistingFilePaths, filePaths.end()); - - return std::move(filePaths); -} -} - -ClangFileSystemWatcher::ClangFileSystemWatcher(Documents &documents) - : documents(documents) -{ - connect(&watcher, - &QFileSystemWatcher::fileChanged, - this, - &ClangFileSystemWatcher::updateDocumentsWithChangedDependencies); -} - -void ClangFileSystemWatcher::addFiles(const QSet<Utf8String> &filePaths) -{ - const auto existingFiles = filterExistingFiles(toStringList(filePaths)); - - if (!existingFiles.isEmpty()) - watcher.addPaths(existingFiles); -} - -void ClangFileSystemWatcher::updateDocumentsWithChangedDependencies(const QString &filePath) -{ - documents.updateDocumentsWithChangedDependency(filePath); - - emit fileChanged(filePath); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangfilesystemwatcher.h b/src/tools/clangbackend/source/clangfilesystemwatcher.h deleted file mode 100644 index 549870eab0..0000000000 --- a/src/tools/clangbackend/source/clangfilesystemwatcher.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <QFileSystemWatcher> -#include <QSet> - -class Utf8String; - -namespace ClangBackEnd { - -class Documents; - -class ClangFileSystemWatcher : public QObject -{ - Q_OBJECT - -public: - ClangFileSystemWatcher(Documents &documents); - - void addFiles(const QSet<Utf8String> &filePaths); - -signals: - void fileChanged(const Utf8String &filePath); - -private: - void updateDocumentsWithChangedDependencies(const QString &filePath); - -private: - QFileSystemWatcher watcher; - Documents &documents; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangfollowsymbol.cpp b/src/tools/clangbackend/source/clangfollowsymbol.cpp deleted file mode 100644 index 81aaeec5c8..0000000000 --- a/src/tools/clangbackend/source/clangfollowsymbol.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangfollowsymbol.h" -#include "clangfollowsymboljob.h" -#include "commandlinearguments.h" -#include "cursor.h" -#include "clangstring.h" -#include "sourcerange.h" -#include "token.h" -#include "clangsupportdebugutils.h" - -#include <utils/qtcassert.h> - -#include <future> - -namespace ClangBackEnd { - -static SourceRange getOperatorRange(const Tokens &tokens, - std::vector<Token>::const_iterator currentToken) -{ - const SourceLocation start = currentToken->location(); - currentToken += 2; - while (currentToken != tokens.cend() && !(currentToken->spelling() == "(")) - ++currentToken; - - return SourceRange(start, currentToken->location()); -} - -static SourceRangeContainer extractMatchingTokenRange(const Cursor &cursor, - const Utf8String &tokenStr) -{ - Tokens tokens(cursor.sourceRange()); - for (auto it = tokens.cbegin(); it != tokens.cend(); ++it) { - const Token ¤tToken = *it; - if (!(tokenStr == currentToken.spelling())) - continue; - - if (cursor.isFunctionLike() || cursor.isConstructorOrDestructor()) { - if (tokenStr == "operator") - return getOperatorRange(tokens, it); - - auto nextIt = it + 1; - if (nextIt == tokens.cend() || !(nextIt->spelling() == "(")) - continue; - } - return currentToken.extent(); - } - return SourceRangeContainer(); -} - -FollowSymbolResult FollowSymbol::followSymbol(CXTranslationUnit tu, - const Cursor &fullCursor, - uint line, - uint column) -{ - Tokens tokens(fullCursor.sourceRange()); - - if (!tokens.size()) { - const Cursor tuCursor(clang_getTranslationUnitCursor(tu)); - tokens = Tokens(tuCursor.sourceRange()); - } - - if (!tokens.size()) - return SourceRangeContainer(); - - std::vector<Cursor> cursors = tokens.annotate(); - const int tokenIndex = tokens.getTokenIndex(tu, line, column); - QTC_ASSERT(tokenIndex >= 0, return SourceRangeContainer()); - - const Utf8String tokenSpelling = tokens[tokenIndex].spelling(); - if (tokenSpelling.isEmpty()) - return SourceRangeContainer(); - - Cursor cursor{cursors[tokenIndex]}; - if (cursor.kind() == CXCursor_CXXThisExpr && tokenSpelling != "this") { // QTCREATORBUG-25342 - cursor.semanticParent().visit([&cursor](CXCursor current, CXCursor parent) { - if (current == cursor && parent.kind == CXCursor_MemberRefExpr - && cursor.sourceLocation() == Cursor(parent).sourceLocation()) { - cursor = parent; - return CXChildVisit_Break; - } - return CXChildVisit_Recurse; - }); - } - - if (cursor.kind() == CXCursor_InclusionDirective) { - CXFile file = clang_getIncludedFile(cursors[tokenIndex].cx()); - const ClangString filename(clang_getFileName(file)); - const SourceLocation loc(tu, clang_getLocation(tu, file, 1, 1)); - FollowSymbolResult result; - result.range = SourceRangeContainer(SourceRange(loc, loc)); - // CLANG-UPGRADE-CHECK: Remove if we don't use empty generated ui_* headers anymore. - if (Utf8String(filename).contains("ui_")) - result.isResultOnlyForFallBack = true; - return result; - } - - // For definitions we can always find a declaration in current TU - if (cursor.isDefinition()) { - if (tokenSpelling == "auto") { - Type type = cursor.type().pointeeType(); - if (!type.isValid()) - type = cursor.type(); - const Cursor declCursor = type.declaration(); - return extractMatchingTokenRange(declCursor, declCursor.spelling()); - } - - const Cursor declCursor = cursor.canonical(); - FollowSymbolResult result; - result.range = extractMatchingTokenRange(declCursor, tokenSpelling); - result.isResultOnlyForFallBack = cursor.isFunctionLike() && declCursor == cursor; - return result; - } - - if (!cursor.isDeclaration()) { - // This is the symbol usage - // We want to return definition - cursor = cursor.referenced(); - if (cursor.isNull()) - return SourceRangeContainer(); - - FollowSymbolResult result; - // We can't find definition in this TU or it's a virtual method call - if (!cursor.isDefinition() || cursor.isVirtualMethod()) - result.isResultOnlyForFallBack = true; - - result.range = extractMatchingTokenRange(cursor, tokenSpelling); - return result; - } - - const bool isFunction = cursor.isFunctionLike(); - cursor = cursor.definition(); - // If we are able to find a definition in current TU - if (!cursor.isNull()) - return extractMatchingTokenRange(cursor, tokenSpelling); - - return FollowSymbolResult({}, isFunction); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangfollowsymbol.h b/src/tools/clangbackend/source/clangfollowsymbol.h deleted file mode 100644 index 7c5469ef66..0000000000 --- a/src/tools/clangbackend/source/clangfollowsymbol.h +++ /dev/null @@ -1,50 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <QVector> - -#include <clang-c/Index.h> - -class Utf8String; - -namespace ClangBackEnd { - -class CommandLineArguments; -class Cursor; -class FollowSymbolResult; -class SourceRangeContainer; - -class FollowSymbol -{ -public: - static FollowSymbolResult followSymbol(CXTranslationUnit tu, - const Cursor &fullCursor, - uint line, - uint column); -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangfollowsymboljob.cpp b/src/tools/clangbackend/source/clangfollowsymboljob.cpp deleted file mode 100644 index c7ac629f80..0000000000 --- a/src/tools/clangbackend/source/clangfollowsymboljob.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangfollowsymboljob.h" - -#include <clangsupport/clangsupportdebugutils.h> -#include <clangsupport/followsymbolmessage.h> -#include <clangsupport/clangcodemodelclientinterface.h> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -IAsyncJob::AsyncPrepareResult FollowSymbolJob::prepareAsyncRun() -{ - const JobRequest jobRequest = context().jobRequest; - QTC_ASSERT(jobRequest.type == JobRequest::Type::RequestFollowSymbol, - return AsyncPrepareResult()); - QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); - - const TranslationUnit translationUnit = *m_translationUnit; - const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput(); - - const quint32 line = jobRequest.line; - const quint32 column = jobRequest.column; - setRunner([translationUnit, line, column]() { - TIME_SCOPE_DURATION("FollowSymbolJobRunner"); - return translationUnit.followSymbol(line, column); - }); - - return AsyncPrepareResult{translationUnit.id()}; -} - -void FollowSymbolJob::finalizeAsyncRun() -{ - if (!context().isOutdated()) { - const AsyncResult result = asyncResult(); - - const FollowSymbolMessage message(m_pinnedFileContainer, - result, - context().jobRequest.ticketNumber); - context().client->followSymbol(message); - } -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangfollowsymboljob.h b/src/tools/clangbackend/source/clangfollowsymboljob.h deleted file mode 100644 index 5e625f97d4..0000000000 --- a/src/tools/clangbackend/source/clangfollowsymboljob.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocumentjob.h" - -#include <clangsupport/followsymbolmessage.h> -#include <clangsupport/sourcerangecontainer.h> - -namespace ClangBackEnd { - -class FollowSymbolJob : public DocumentJob<FollowSymbolResult> -{ -public: - using AsyncResult = FollowSymbolResult; - - AsyncPrepareResult prepareAsyncRun() override; - void finalizeAsyncRun() override; -}; -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangiasyncjob.cpp b/src/tools/clangbackend/source/clangiasyncjob.cpp deleted file mode 100644 index 2ce218e99e..0000000000 --- a/src/tools/clangbackend/source/clangiasyncjob.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangiasyncjob.h" - -Q_LOGGING_CATEGORY(jobsLog, "qtc.clangbackend.jobs", QtWarningMsg); - -namespace ClangBackEnd { - -IAsyncJob::IAsyncJob() - : m_context(JobContext()) -{ -} - -IAsyncJob::~IAsyncJob() -{ -} - -JobContext IAsyncJob::context() const -{ - return m_context; -} - -void IAsyncJob::setContext(const JobContext &context) -{ - m_context = context; -} - -IAsyncJob::FinishedHandler IAsyncJob::finishedHandler() const -{ - return m_finishedHandler; -} - -void IAsyncJob::setFinishedHandler(const IAsyncJob::FinishedHandler &finishedHandler) -{ - m_finishedHandler = finishedHandler; -} - -bool IAsyncJob::isFinished() const -{ - return m_isFinished; -} - -void IAsyncJob::setIsFinished(bool isFinished) -{ - m_isFinished = isFinished; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangiasyncjob.h b/src/tools/clangbackend/source/clangiasyncjob.h deleted file mode 100644 index 9d17e874f1..0000000000 --- a/src/tools/clangbackend/source/clangiasyncjob.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangjobcontext.h" - -#include <QFuture> -#include <QLoggingCategory> - -#include <functional> - -Q_DECLARE_LOGGING_CATEGORY(jobsLog); -#define qCDebugJobs() qCDebug(jobsLog) << "[" << m_logTag << "]" - -namespace ClangBackEnd { - -class IAsyncJob -{ -public: - struct AsyncPrepareResult { - operator bool() const { return !translationUnitId.isEmpty(); } - Utf8String translationUnitId; - }; - -public: - IAsyncJob(); - virtual ~IAsyncJob(); - - JobContext context() const; - void setContext(const JobContext &context); - - using FinishedHandler = std::function<void(IAsyncJob *job)>; - FinishedHandler finishedHandler() const; - void setFinishedHandler(const FinishedHandler &finishedHandler); - - virtual AsyncPrepareResult prepareAsyncRun() = 0; - virtual QFuture<void> runAsync() = 0; - virtual void finalizeAsyncRun() = 0; - - virtual void preventFinalization() = 0; - -public: // for tests - bool isFinished() const; - void setIsFinished(bool isFinished); - -private: - bool m_isFinished = false; - FinishedHandler m_finishedHandler; - JobContext m_context; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangjobcontext.cpp b/src/tools/clangbackend/source/clangjobcontext.cpp deleted file mode 100644 index 59f0c1001e..0000000000 --- a/src/tools/clangbackend/source/clangjobcontext.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangiasyncjob.h" - -#include "clangdocuments.h" - -namespace ClangBackEnd { - -JobContext::JobContext(const JobRequest &jobRequest, - Documents *documents, - UnsavedFiles *unsavedFiles, - ClangCodeModelClientInterface *clientInterface) - : jobRequest(jobRequest) - , documents(documents) - , unsavedFiles(unsavedFiles) - , client(clientInterface) -{ -} - -Document JobContext::documentForJobRequest() const -{ - return documents->document(jobRequest.filePath); -} - -bool JobContext::isOutdated() const -{ - return !isDocumentOpen() || documentRevisionChanged(); -} - -bool JobContext::isDocumentOpen() const -{ - const bool hasDocument = documents->hasDocument(jobRequest.filePath); - if (!hasDocument) - qCDebug(jobsLog) << "Document already closed for results of" << jobRequest; - - return hasDocument; -} - -bool JobContext::documentRevisionChanged() const -{ - const Document &document = documents->document(jobRequest.filePath); - const bool revisionChanged = document.documentRevision() != jobRequest.documentRevision; - - if (revisionChanged) - qCDebug(jobsLog) << "Document revision changed for results of" << jobRequest; - - return revisionChanged; -} - -} // ClangBackEnd diff --git a/src/tools/clangbackend/source/clangjobcontext.h b/src/tools/clangbackend/source/clangjobcontext.h deleted file mode 100644 index 629d8320bd..0000000000 --- a/src/tools/clangbackend/source/clangjobcontext.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangjobrequest.h" - -namespace ClangBackEnd { - -class ClangCodeModelClientInterface; -class Document; -class Documents; -class UnsavedFiles; - -class JobContext -{ -public: - JobContext() = default; - JobContext(const JobRequest &jobRequest, - Documents *documents, - UnsavedFiles *unsavedFiles, - ClangCodeModelClientInterface *client); - - Document documentForJobRequest() const; - - bool isOutdated() const; - bool isDocumentOpen() const; - bool documentRevisionChanged() const; - -public: - JobRequest jobRequest; - Documents *documents = nullptr; - UnsavedFiles *unsavedFiles = nullptr; - ClangCodeModelClientInterface *client = nullptr; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangjobqueue.cpp b/src/tools/clangbackend/source/clangjobqueue.cpp deleted file mode 100644 index 1be56b3b6c..0000000000 --- a/src/tools/clangbackend/source/clangjobqueue.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangiasyncjob.h" -#include "clangjobqueue.h" -#include "clangdocument.h" -#include "clangdocuments.h" -#include "clangtranslationunits.h" -#include "unsavedfiles.h" - -#include <utils/algorithm.h> - -namespace ClangBackEnd { - -JobQueue::JobQueue(Documents &documents, const Utf8String &logTag) - : m_documents(documents) - , m_logTag(logTag) -{ -} - -bool JobQueue::add(const JobRequest &job) -{ - QString notAddableReason; - if (isJobRequestAddable(job, notAddableReason)) { - qCDebugJobs() << "Adding" << job; - m_queue.append(job); - return true; - } else { - qCDebugJobs() << "Not adding" << job << notAddableReason; - cancelJobRequest(job); - return false; - } -} - -int JobQueue::size() const -{ - return m_queue.size(); -} - -JobRequests JobQueue::processQueue() -{ - removeExpiredRequests(); - prioritizeRequests(); - const JobRequests jobsToRun = takeJobRequestsToRunNow(); - - return jobsToRun; -} - -void JobQueue::removeExpiredRequests() -{ - JobRequests cleanedRequests; - - foreach (const JobRequest &jobRequest, m_queue) { - try { - QString expirationReason; - if (isJobRequestExpired(jobRequest, expirationReason)) { - qCDebugJobs() << "Expired:" << jobRequest << expirationReason; - cancelJobRequest(jobRequest); - } else { - cleanedRequests.append(jobRequest); - } - } catch (const std::exception &exception) { - qWarning() << "Error in Jobs::removeOutDatedRequests for" - << jobRequest << ":" << exception.what(); - } - } - - m_queue = cleanedRequests; -} - -bool JobQueue::isJobRequestAddable(const JobRequest &jobRequest, QString ¬AddableReason) -{ - if (m_queue.contains(jobRequest)) { - notAddableReason = "duplicate request in queue"; - return false; - } - - if (isJobRunningForJobRequest(jobRequest)) { - notAddableReason = "duplicate request for already running job"; - return false; - } - - if (!m_documents.hasDocument(jobRequest.filePath)) { - notAddableReason = "document already closed"; - return false; - } - - const Document document = m_documents.document(jobRequest.filePath); - if (!document.isIntact()) { - notAddableReason = "document not intact"; - return false; - } - - return true; -} - -bool JobQueue::isJobRequestExpired(const JobRequest &jobRequest, QString &expirationReason) -{ - const JobRequest::ExpirationConditions conditions = jobRequest.expirationConditions; - const UnsavedFiles unsavedFiles = m_documents.unsavedFiles(); - using Condition = JobRequest::ExpirationCondition; - - if (conditions.testFlag(Condition::UnsavedFilesChanged)) { - if (jobRequest.unsavedFilesChangeTimePoint != unsavedFiles.lastChangeTimePoint()) { - expirationReason = "outdated unsaved files"; - return true; - } - } - - if (conditions.testFlag(Condition::DocumentClosed)) { - if (!m_documents.hasDocument(jobRequest.filePath)) { - expirationReason = "document already closed"; - return true; - } - - const Document document - = m_documents.document(jobRequest.filePath); - if (!document.isIntact()) { - expirationReason = "document not intact"; - return true; - } - - if (conditions.testFlag(Condition::DocumentRevisionChanged)) { - if (document.documentRevision() > jobRequest.documentRevision) { - expirationReason = "changed document revision"; - return true; - } - } - } - - return false; -} - -static int priority(const Document &document) -{ - int thePriority = 0; - - if (document.isUsedByCurrentEditor()) - thePriority += 1000; - - if (document.isVisibleInEditor()) - thePriority += 100; - - return thePriority; -} - -void JobQueue::prioritizeRequests() -{ - const auto lessThan = [this] (const JobRequest &r1, const JobRequest &r2) { - // TODO: Getting the TU is O(n) currently, so this might become expensive for large n. - const Document &t1 = m_documents.document(r1.filePath); - const Document &t2 = m_documents.document(r2.filePath); - - return priority(t1) > priority(t2); - }; - - std::stable_sort(m_queue.begin(), m_queue.end(), lessThan); -} - -void JobQueue::cancelJobRequest(const JobRequest &jobRequest) -{ - if (m_cancelJobRequest) - m_cancelJobRequest(jobRequest); -} - -bool JobQueue::areRunConditionsMet(const JobRequest &request, const Document &document) const -{ - using Condition = JobRequest::RunCondition; - const JobRequest::RunConditions conditions = request.runConditions; - - if (conditions.testFlag(Condition::DocumentSuspended) && !document.isSuspended()) { - qCDebugJobs() << "Not choosing due to unsuspended document:" << request; - return false; - } - - if (conditions.testFlag(Condition::DocumentUnsuspended) && document.isSuspended()) { - qCDebugJobs() << "Not choosing due to suspended document:" << request; - return false; - } - - if (conditions.testFlag(Condition::DocumentVisible) && !document.isVisibleInEditor()) { - qCDebugJobs() << "Not choosing due to invisible document:" << request; - return false; - } - - if (conditions.testFlag(Condition::DocumentNotVisible) && document.isVisibleInEditor()) { - qCDebugJobs() << "Not choosing due to visible document:" << request; - return false; - } - - if (conditions.testFlag(Condition::CurrentDocumentRevision)) { - if (document.isDirty()) { - // TODO: If the document is dirty due to a project update, - // references are processes later than ideal. - qCDebugJobs() << "Not choosing due to dirty document:" << request; - return false; - } - - if (request.documentRevision != document.documentRevision()) { - qCDebugJobs() << "Not choosing due to revision mismatch:" << request; - return false; - } - } - - if (conditions.testFlag(Condition::DocumentParsed) - && !document.translationUnits().hasParsedTranslationUnit()) { - qCDebugJobs() << "Not choosing due to not yet parsed translation unit:" << request; - return false; - } - - return true; -} - -JobRequests JobQueue::takeJobRequestsToRunNow() -{ - JobRequests jobsToRun; - using TranslationUnitIds = QSet<Utf8String>; - TranslationUnitIds translationUnitsScheduledForThisRun; - - for (int pos = 0; pos < m_queue.size(); ++pos) { - const JobRequest &request = m_queue.at(pos); - - try { - const Document &document = m_documents.document(request.filePath); - - if (!areRunConditionsMet(request, document)) - continue; - - const Utf8String id = document.translationUnit(request.preferredTranslationUnit).id(); - if (translationUnitsScheduledForThisRun.contains(id)) - continue; - - if (isJobRunningForTranslationUnit(id)) - continue; - - translationUnitsScheduledForThisRun.insert(id); - jobsToRun += request; - m_queue.removeAt(pos--); - } catch (const std::exception &exception) { - qWarning() << "Error in Jobs::takeJobRequestsToRunNow for" - << request << ":" << exception.what(); - } - } - - return jobsToRun; -} - -bool JobQueue::isJobRunningForTranslationUnit(const Utf8String &translationUnitId) -{ - if (m_isJobRunningForTranslationUnitHandler) - return m_isJobRunningForTranslationUnitHandler(translationUnitId); - - return false; -} - -bool JobQueue::isJobRunningForJobRequest(const JobRequest &jobRequest) -{ - if (m_isJobRunningForJobRequestHandler) - return m_isJobRunningForJobRequestHandler(jobRequest); - - return false; -} - -void JobQueue::setIsJobRunningForTranslationUnitHandler( - const IsJobRunningForTranslationUnitHandler &isJobRunningHandler) -{ - m_isJobRunningForTranslationUnitHandler = isJobRunningHandler; -} - -void JobQueue::setIsJobRunningForJobRequestHandler( - const JobQueue::IsJobRunningForJobRequestHandler &isJobRunningHandler) -{ - m_isJobRunningForJobRequestHandler = isJobRunningHandler; -} - -void JobQueue::setCancelJobRequest(const JobQueue::CancelJobRequest &cancelJobRequest) -{ - m_cancelJobRequest = cancelJobRequest; -} - -JobRequests &JobQueue::queue() -{ - return m_queue; -} - -const JobRequests &JobQueue::queue() const -{ - return m_queue; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangjobqueue.h b/src/tools/clangbackend/source/clangjobqueue.h deleted file mode 100644 index 2e0effaf9d..0000000000 --- a/src/tools/clangbackend/source/clangjobqueue.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangjobrequest.h" - -#include <functional> - -namespace ClangBackEnd { - -class Documents; - -class JobQueue -{ -public: - JobQueue(Documents &documents, const Utf8String &logTag = Utf8String()); - - bool add(const JobRequest &job); - - JobRequests processQueue(); - - using IsJobRunningForTranslationUnitHandler = std::function<bool(const Utf8String &)>; - void setIsJobRunningForTranslationUnitHandler( - const IsJobRunningForTranslationUnitHandler &isJobRunningHandler); - - using IsJobRunningForJobRequestHandler = std::function<bool(const JobRequest &)>; - void setIsJobRunningForJobRequestHandler( - const IsJobRunningForJobRequestHandler &isJobRunningHandler); - - using CancelJobRequest = std::function<void(const JobRequest &)>; - void setCancelJobRequest(const CancelJobRequest &cancelJobRequest); - -public: // for tests - JobRequests &queue(); - const JobRequests &queue() const; - int size() const; - void prioritizeRequests(); - -private: - bool areRunConditionsMet(const JobRequest &request, const Document &document) const; - void cancelJobRequest(const JobRequest &jobRequest); - bool isJobRunningForTranslationUnit(const Utf8String &translationUnitId); - bool isJobRunningForJobRequest(const JobRequest &jobRequest); - JobRequests takeJobRequestsToRunNow(); - void removeExpiredRequests(); - bool isJobRequestAddable(const JobRequest &jobRequest, QString ¬AddableReason); - bool isJobRequestExpired(const JobRequest &jobRequest, QString &expirationReason); - -private: - Documents &m_documents; - Utf8String m_logTag; - - IsJobRunningForTranslationUnitHandler m_isJobRunningForTranslationUnitHandler; - IsJobRunningForJobRequestHandler m_isJobRunningForJobRequestHandler; - CancelJobRequest m_cancelJobRequest; - - JobRequests m_queue; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangjobrequest.cpp b/src/tools/clangbackend/source/clangjobrequest.cpp deleted file mode 100644 index bbf2f726e6..0000000000 --- a/src/tools/clangbackend/source/clangjobrequest.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangjobrequest.h" - -#include "clangcompletecodejob.h" -#include "clangfollowsymboljob.h" -#include "clangparsesupportivetranslationunitjob.h" -#include "clangrequestannotationsjob.h" -#include "clangrequestreferencesjob.h" -#include "clangrequesttooltipjob.h" -#include "clangresumedocumentjob.h" -#include "clangsuspenddocumentjob.h" -#include "clangupdateannotationsjob.h" -#include "clangupdateextraannotationsjob.h" - -#include <clangsupport/clangcodemodelclientinterface.h> -#include <clangsupport/completionsmessage.h> -#include <clangsupport/followsymbolmessage.h> -#include <clangsupport/referencesmessage.h> -#include <clangsupport/tooltipmessage.h> - -#include <utils/qtcassert.h> - -#include <QFileInfo> - -#include <ostream> - -namespace ClangBackEnd { - -#define RETURN_TEXT_FOR_CASE(enumValue) case JobRequest::Type::enumValue: return #enumValue -static const char *JobRequestTypeToText(JobRequest::Type type) -{ - switch (type) { - RETURN_TEXT_FOR_CASE(Invalid); - RETURN_TEXT_FOR_CASE(UpdateAnnotations); - RETURN_TEXT_FOR_CASE(UpdateExtraAnnotations); - RETURN_TEXT_FOR_CASE(ParseSupportiveTranslationUnit); - RETURN_TEXT_FOR_CASE(RequestCompletions); - RETURN_TEXT_FOR_CASE(RequestAnnotations); - RETURN_TEXT_FOR_CASE(RequestReferences); - RETURN_TEXT_FOR_CASE(RequestFollowSymbol); - RETURN_TEXT_FOR_CASE(RequestToolTip); - RETURN_TEXT_FOR_CASE(SuspendDocument); - RETURN_TEXT_FOR_CASE(ResumeDocument); - } - - return "UnhandledJobRequestType"; -} -#undef RETURN_TEXT_FOR_CASE - -#define RETURN_TEXT_FOR_CASE(enumValue) case PreferredTranslationUnit::enumValue: return #enumValue -const char *preferredTranslationUnitToText(PreferredTranslationUnit type) -{ - switch (type) { - RETURN_TEXT_FOR_CASE(RecentlyParsed); - RETURN_TEXT_FOR_CASE(PreviouslyParsed); - RETURN_TEXT_FOR_CASE(LastUninitialized); - } - - return "UnhandledPreferredTranslationUnitType"; -} -#undef RETURN_TEXT_FOR_CASE - -QDebug operator<<(QDebug debug, JobRequest::Type type) -{ - debug << JobRequestTypeToText(type); - - return debug; -} - -std::ostream &operator<<(std::ostream &os, JobRequest::Type type) -{ - return os << JobRequestTypeToText(type); -} - -std::ostream &operator<<(std::ostream &os, PreferredTranslationUnit preferredTranslationUnit) -{ - return os << preferredTranslationUnitToText(preferredTranslationUnit); -} - -QDebug operator<<(QDebug debug, const JobRequest &jobRequest) -{ - debug.nospace() << "Job<" - << jobRequest.id - << "," - << QFileInfo(jobRequest.filePath).fileName() - << "," - << JobRequestTypeToText(jobRequest.type) - << "," - << preferredTranslationUnitToText(jobRequest.preferredTranslationUnit) - << ">"; - - return debug.space(); -} - -static JobRequest::ExpirationConditions expirationConditionsForType(JobRequest::Type type) -{ - using Type = JobRequest::Type; - using Condition = JobRequest::ExpirationCondition; - using Conditions = JobRequest::ExpirationConditions; - - switch (type) { - case Type::UpdateAnnotations: - case Type::UpdateExtraAnnotations: - return Conditions(Condition::AnythingChanged); - case Type::RequestReferences: - case Type::RequestAnnotations: - case Type::RequestToolTip: - case Type::RequestFollowSymbol: - return Conditions(Condition::DocumentClosed) - | Conditions(Condition::DocumentRevisionChanged); - default: - return Condition::DocumentClosed; - } -} - -static JobRequest::RunConditions conditionsForType(JobRequest::Type type) -{ - using Type = JobRequest::Type; - using Condition = JobRequest::RunCondition; - using Conditions = JobRequest::RunConditions; - - if (type == Type::SuspendDocument) { - return Conditions(Condition::DocumentUnsuspended) - | Conditions(Condition::DocumentNotVisible); - } - - if (type == Type::ResumeDocument) { - return Conditions(Condition::DocumentSuspended) - | Conditions(Condition::DocumentVisible); - } - - Conditions conditions = Conditions(Condition::DocumentUnsuspended) - | Conditions(Condition::DocumentVisible); - - if (type == Type::RequestReferences || type == Type::RequestFollowSymbol - || type == Type::RequestToolTip || type == Type::UpdateExtraAnnotations) { - conditions |= Condition::CurrentDocumentRevision; - } - - if (type != Type::UpdateAnnotations && type != Type::ParseSupportiveTranslationUnit) - conditions |= Condition::DocumentParsed; - - return conditions; -} - -bool JobRequest::isTakeOverable() const -{ - // When new project information comes in and there are unprocessed jobs - // in the queue, we need to decide what to do with them. - - switch (type) { - // Never discard these as the client side might wait for a response. - case Type::RequestCompletions: - case Type::RequestReferences: - case Type::RequestFollowSymbol: - case Type::RequestToolTip: - return true; - - // Discard this one as UpdateAnnotations will have the same effect. - case Type::RequestAnnotations: - - // Discard Suspend because the document will be cleared anyway. - // Discard Resume because a (re)parse will happen on demand. - case Type::SuspendDocument: - case Type::ResumeDocument: - - // Discard these as they are initial jobs that will be recreated on demand - // anyway. - case Type::UpdateAnnotations: - case Type::UpdateExtraAnnotations: - - // Discard these as they only make sense in a row. Avoid splitting them up. - case Type::ParseSupportiveTranslationUnit: - - case Type::Invalid: - return false; - } - - return false; -} - -JobRequest::JobRequest(Type type) -{ - static quint64 idCounter = 0; - - id = ++idCounter; - this->type = type; - runConditions = conditionsForType(type); - expirationConditions = expirationConditionsForType(type); -} - -IAsyncJob *JobRequest::createJob() const -{ - switch (type) { - case JobRequest::Type::Invalid: - QTC_CHECK(false && "Cannot create job for invalid job request."); - break; - case JobRequest::Type::UpdateAnnotations: - return new UpdateAnnotationsJob(); - case JobRequest::Type::UpdateExtraAnnotations: - return new UpdateExtraAnnotationsJob(); - case JobRequest::Type::ParseSupportiveTranslationUnit: - return new ParseSupportiveTranslationUnitJob(); - case JobRequest::Type::RequestCompletions: - return new CompleteCodeJob(); - case JobRequest::Type::RequestAnnotations: - return new RequestAnnotationsJob(); - case JobRequest::Type::RequestReferences: - return new RequestReferencesJob(); - case JobRequest::Type::RequestToolTip: - return new RequestToolTipJob(); - case JobRequest::Type::RequestFollowSymbol: - return new FollowSymbolJob(); - case JobRequest::Type::SuspendDocument: - return new SuspendDocumentJob(); - case JobRequest::Type::ResumeDocument: - return new ResumeDocumentJob(); - } - - return nullptr; -} - -void JobRequest::cancelJob(ClangCodeModelClientInterface &client) const -{ - // If a job request with a ticket number is cancelled, the plugin side - // must get back some results in order to clean up the state there. - - switch (type) { - case JobRequest::Type::Invalid: - case JobRequest::Type::UpdateAnnotations: - case JobRequest::Type::UpdateExtraAnnotations: - case JobRequest::Type::ParseSupportiveTranslationUnit: - case JobRequest::Type::RequestAnnotations: - case JobRequest::Type::SuspendDocument: - case JobRequest::Type::ResumeDocument: - break; - case JobRequest::Type::RequestReferences: - client.references(ReferencesMessage(FileContainer(), - QVector<SourceRangeContainer>(), - false, - ticketNumber)); - break; - case JobRequest::Type::RequestToolTip: - client.tooltip(ToolTipMessage(FileContainer(), ToolTipInfo(), ticketNumber)); - break; - case JobRequest::Type::RequestCompletions: - client.completions(CompletionsMessage(CodeCompletions(), ticketNumber)); - break; - case JobRequest::Type::RequestFollowSymbol: - client.followSymbol( - FollowSymbolMessage(FileContainer(), SourceRangeContainer(), ticketNumber)); - break; - } -} - -bool JobRequest::operator==(const JobRequest &other) const -{ - return type == other.type - && expirationConditions == other.expirationConditions - && runConditions == other.runConditions - - && filePath == other.filePath - && unsavedFilesChangeTimePoint == other.unsavedFilesChangeTimePoint - && documentRevision == other.documentRevision - && preferredTranslationUnit == other.preferredTranslationUnit - - && line == other.line - && column == other.column - && ticketNumber == other.ticketNumber; - - // Additional members that are not compared here explicitly are - // supposed to depend on the already compared ones. -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangjobrequest.h b/src/tools/clangbackend/source/clangjobrequest.h deleted file mode 100644 index fde2eca4db..0000000000 --- a/src/tools/clangbackend/source/clangjobrequest.h +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangbackend_global.h" -#include "clangclock.h" - -#include <utf8string.h> -#include <utf8stringvector.h> - -#include <QFlags> -#include <QDebug> -#include <QVector> - -#include <functional> - -namespace ClangBackEnd { - -class ClangCodeModelClientInterface; -class Document; -class IAsyncJob; - -class JobRequest -{ -public: - enum class Type { - Invalid, - - UpdateAnnotations, - UpdateExtraAnnotations, - - ParseSupportiveTranslationUnit, - - RequestCompletions, - RequestAnnotations, - RequestReferences, - RequestFollowSymbol, - RequestToolTip, - - SuspendDocument, - ResumeDocument, - }; - - enum class RunCondition { - NoCondition = 1 << 0, - DocumentVisible = 1 << 1, - DocumentNotVisible = 1 << 2, - DocumentSuspended = 1 << 3, - DocumentUnsuspended = 1 << 4, - DocumentParsed = 1 << 5, - CurrentDocumentRevision = 1 << 6, - }; - Q_DECLARE_FLAGS(RunConditions, RunCondition) - - enum class ExpirationCondition { - Never = 1 << 0, - - DocumentClosed = 1 << 1, - DocumentRevisionChanged = 1 << 2, // Only effective if DocumentIsClosed is also set - UnsavedFilesChanged = 1 << 3, - - AnythingChanged = DocumentClosed - | DocumentRevisionChanged - | UnsavedFilesChanged, - }; - Q_DECLARE_FLAGS(ExpirationConditions, ExpirationCondition) - -public: - JobRequest(Type type = Type::Invalid); - - IAsyncJob *createJob() const; - void cancelJob(ClangCodeModelClientInterface &client) const; - bool isTakeOverable() const; - - bool operator==(const JobRequest &other) const; - friend QDebug operator<<(QDebug debug, const JobRequest &jobRequest); - -public: - quint64 id = 0; - Type type; - ExpirationConditions expirationConditions; - RunConditions runConditions; - - // General - Utf8String filePath; - TimePoint unsavedFilesChangeTimePoint; - uint documentRevision = 0; - PreferredTranslationUnit preferredTranslationUnit = PreferredTranslationUnit::RecentlyParsed; - - // Specific to some jobs - quint32 line = 0; - quint32 column = 0; - qint32 funcNameStartLine = -1; - qint32 funcNameStartColumn = -1; - quint64 ticketNumber = 0; - Utf8String textCodecName; - bool localReferences = false; -}; - -using JobRequests = QVector<JobRequest>; - -std::ostream &operator<<(std::ostream &os, JobRequest::Type type); -std::ostream &operator<<(std::ostream &os, PreferredTranslationUnit preferredTranslationUnit); - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangjobs.cpp b/src/tools/clangbackend/source/clangjobs.cpp deleted file mode 100644 index 51b875f65f..0000000000 --- a/src/tools/clangbackend/source/clangjobs.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangjobs.h" - -#include "clangdocument.h" -#include "clangiasyncjob.h" - -#include <QDebug> -#include <QLoggingCategory> - -#include <utils/algorithm.h> -#include <utils/futuresynchronizer.h> -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -Jobs::Jobs(Documents &documents, - UnsavedFiles &unsavedFiles, - ClangCodeModelClientInterface &client, - const Utf8String &logTag) - : m_documents(documents) - , m_unsavedFiles(unsavedFiles) - , m_client(client) - , m_logTag(logTag) - , m_queue(documents, logTag) -{ - m_queue.setIsJobRunningForTranslationUnitHandler([this](const Utf8String &translationUnitId) { - return isJobRunningForTranslationUnit(translationUnitId); - }); - m_queue.setIsJobRunningForJobRequestHandler([this](const JobRequest &jobRequest) { - return isJobRunningForJobRequest(jobRequest); - }); - m_queue.setCancelJobRequest([this](const JobRequest &jobRequest) { - jobRequest.cancelJob(m_client); - }); -} - -Jobs::~Jobs() -{ - foreach (IAsyncJob *asyncJob, m_running.keys()) - asyncJob->preventFinalization(); - - Utils::FutureSynchronizer waitForFinishedJobs; - foreach (const RunningJob &runningJob, m_running.values()) - waitForFinishedJobs.addFuture(runningJob.future); - - foreach (IAsyncJob *asyncJob, m_running.keys()) - delete asyncJob; -} - -JobRequest Jobs::createJobRequest(const Document &document, - JobRequest::Type type, - PreferredTranslationUnit preferredTranslationUnit) const -{ - JobRequest jobRequest(type); - jobRequest.filePath = document.filePath(); - jobRequest.unsavedFilesChangeTimePoint = m_unsavedFiles.lastChangeTimePoint(); - jobRequest.documentRevision = document.documentRevision(); - jobRequest.preferredTranslationUnit = preferredTranslationUnit; - - return jobRequest; -} - -void Jobs::add(const JobRequest &job) -{ - m_queue.add(job); -} - -void Jobs::add(const Document &document, - JobRequest::Type type, - PreferredTranslationUnit preferredTranslationUnit) -{ - const JobRequest jobRequest = createJobRequest(document, type, preferredTranslationUnit); - m_queue.add(jobRequest); -} - -JobRequests Jobs::process() -{ - const JobRequests jobsToRun = m_queue.processQueue(); - const JobRequests jobsStarted = runJobs(jobsToRun); - - QTC_CHECK(jobsToRun.size() == jobsStarted.size()); - - return jobsStarted; -} - -JobRequests Jobs::stop() -{ - // Take the queued jobs to prevent processing them. - const JobRequests queuedJobs = queue(); - queue().clear(); - - // Wait until currently running jobs finish. - Utils::FutureSynchronizer waitForFinishedJobs; - foreach (const RunningJob &runningJob, m_running.values()) - waitForFinishedJobs.addFuture(runningJob.future); - - return queuedJobs; -} - -Jobs::JobFinishedCallback Jobs::finishedCallback() const -{ - return m_jobFinishedCallback; -} - -JobRequests Jobs::runJobs(const JobRequests &jobsRequests) -{ - JobRequests jobsStarted; - - foreach (const JobRequest &jobRequest, jobsRequests) { - if (runJob(jobRequest)) - jobsStarted += jobRequest; - } - - return jobsStarted; -} - -bool Jobs::runJob(const JobRequest &jobRequest) -{ - IAsyncJob *asyncJob = jobRequest.createJob(); - QTC_ASSERT(asyncJob, return false); - - JobContext context(jobRequest, &m_documents, &m_unsavedFiles, &m_client); - asyncJob->setContext(context); - - if (const IAsyncJob::AsyncPrepareResult prepareResult = asyncJob->prepareAsyncRun()) { - qCDebugJobs() << "Running" << jobRequest - << "with TranslationUnit" << prepareResult.translationUnitId; - - asyncJob->setFinishedHandler([this](IAsyncJob *asyncJob){ onJobFinished(asyncJob); }); - const QFuture<void> future = asyncJob->runAsync(); - - const RunningJob runningJob{jobRequest, prepareResult.translationUnitId, future}; - m_running.insert(asyncJob, runningJob); - return true; - } else { - qCDebugJobs() << "Preparation failed for " << jobRequest; - delete asyncJob; - } - - return false; -} - -void Jobs::onJobFinished(IAsyncJob *asyncJob) -{ - qCDebugJobs() << "Finishing" << asyncJob->context().jobRequest; - - if (m_jobFinishedCallback) { - const RunningJob runningJob = m_running.value(asyncJob); - if (m_jobFinishedCallback(runningJob, asyncJob)) - return; - } - - m_running.remove(asyncJob); - delete asyncJob; - - process(); -} - -Jobs::JobFinishedCallback Jobs::jobFinishedCallback() const -{ - return m_jobFinishedCallback; -} - -void Jobs::setJobFinishedCallback(const JobFinishedCallback &jobFinishedCallback) -{ - m_jobFinishedCallback = jobFinishedCallback; -} - -QList<Jobs::RunningJob> Jobs::runningJobs() const -{ - return m_running.values(); -} - -JobRequests &Jobs::queue() -{ - return m_queue.queue(); -} - -const JobRequests &Jobs::queue() const -{ - return m_queue.queue(); -} - -bool Jobs::isJobRunningForTranslationUnit(const Utf8String &translationUnitId) const -{ - const auto hasTranslationUnitId = [translationUnitId](const RunningJob &runningJob) { - return runningJob.translationUnitId == translationUnitId; - }; - - return Utils::anyOf(m_running.values(), hasTranslationUnitId); -} - -bool Jobs::isJobRunningForJobRequest(const JobRequest &jobRequest) const -{ - const auto hasJobRequest = [jobRequest](const RunningJob &runningJob) { - return runningJob.jobRequest == jobRequest; - }; - - return Utils::anyOf(m_running.values(), hasJobRequest); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangjobs.h b/src/tools/clangbackend/source/clangjobs.h deleted file mode 100644 index 3d8af16fe4..0000000000 --- a/src/tools/clangbackend/source/clangjobs.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangjobqueue.h" - -#include <clangsupport/clangcodemodelclientinterface.h> - -#include <QFuture> - -#include <functional> - -namespace ClangBackEnd { - -class ClangCodeModelClientInterface; -class Documents; -class IAsyncJob; -class UnsavedFiles; - -class Jobs -{ -public: - struct RunningJob { - JobRequest jobRequest; - Utf8String translationUnitId; - QFuture<void> future; - }; - - using RunningJobs = QHash<IAsyncJob *, RunningJob>; - using JobFinishedCallback = std::function<bool(RunningJob, IAsyncJob *)>; - -public: - Jobs(Documents &documents, - UnsavedFiles &unsavedFiles, - ClangCodeModelClientInterface &client, - const Utf8String &logTag = Utf8String()); - ~Jobs(); - - JobRequest createJobRequest(const Document &document, JobRequest::Type type, - PreferredTranslationUnit preferredTranslationUnit - = PreferredTranslationUnit::RecentlyParsed) const; - - void add(const JobRequest &job); - void add(const Document &document, - JobRequest::Type type, - PreferredTranslationUnit preferredTranslationUnit - = PreferredTranslationUnit::RecentlyParsed); - - JobRequests process(); - JobRequests stop(); - - JobFinishedCallback finishedCallback() const; - void setJobFinishedCallback(const JobFinishedCallback &jobFinishedCallback); - -public /*for tests*/: - QList<RunningJob> runningJobs() const; - JobRequests &queue(); - const JobRequests &queue() const; - bool isJobRunningForTranslationUnit(const Utf8String &translationUnitId) const; - bool isJobRunningForJobRequest(const JobRequest &jobRequest) const; - JobFinishedCallback jobFinishedCallback() const; - -private: - JobRequests runJobs(const JobRequests &jobRequest); - bool runJob(const JobRequest &jobRequest); - void onJobFinished(IAsyncJob *asyncJob); - -private: - Documents &m_documents; - UnsavedFiles &m_unsavedFiles; - ClangCodeModelClientInterface &m_client; - Utf8String m_logTag; - - JobQueue m_queue; - RunningJobs m_running; - JobFinishedCallback m_jobFinishedCallback; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangparsesupportivetranslationunitjob.cpp b/src/tools/clangbackend/source/clangparsesupportivetranslationunitjob.cpp deleted file mode 100644 index 126fac2fbe..0000000000 --- a/src/tools/clangbackend/source/clangparsesupportivetranslationunitjob.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangparsesupportivetranslationunitjob.h" - -#include <clangsupport/clangsupportdebugutils.h> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -IAsyncJob::AsyncPrepareResult ParseSupportiveTranslationUnitJob::prepareAsyncRun() -{ - const JobRequest jobRequest = context().jobRequest; - QTC_ASSERT(jobRequest.type == JobRequest::Type::ParseSupportiveTranslationUnit, return AsyncPrepareResult()); - QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); - - const TranslationUnit translationUnit = *m_translationUnit; - const TranslationUnitUpdateInput updateInput = m_pinnedDocument.createUpdateInput(); - setRunner([translationUnit, updateInput]() { - TIME_SCOPE_DURATION("ParseSupportiveTranslationUnitJob"); - - TranslationUnitUpdateInput theUpdateInput = updateInput; - theUpdateInput.parseNeeded = true; - - return translationUnit.update(updateInput); - }); - - return AsyncPrepareResult{translationUnit.id()}; -} - -void ParseSupportiveTranslationUnitJob::finalizeAsyncRun() -{ - if (!context().isOutdated()) { - const AsyncResult result = asyncResult(); - m_pinnedDocument.incorporateUpdaterResult(result); - } -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/clangparsesupportivetranslationunitjob.h b/src/tools/clangbackend/source/clangparsesupportivetranslationunitjob.h deleted file mode 100644 index 5a0cfec183..0000000000 --- a/src/tools/clangbackend/source/clangparsesupportivetranslationunitjob.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocumentjob.h" -#include "clangtranslationunitupdater.h" - -namespace ClangBackEnd { - -class ParseSupportiveTranslationUnitJob : public DocumentJob<TranslationUnitUpdateResult> -{ -public: - using AsyncResult = TranslationUnitUpdateResult; - - AsyncPrepareResult prepareAsyncRun() override; - void finalizeAsyncRun() override; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangreferencescollector.cpp b/src/tools/clangbackend/source/clangreferencescollector.cpp deleted file mode 100644 index a750beac03..0000000000 --- a/src/tools/clangbackend/source/clangreferencescollector.cpp +++ /dev/null @@ -1,226 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangreferencescollector.h" - -#include "clangstring.h" -#include "cursor.h" -#include "sourcerange.h" -#include "token.h" - -#include <clangsupport/sourcerangecontainer.h> -#include <utils/qtcassert.h> - -#include <utf8string.h> - -#include <QDebug> - -namespace ClangBackEnd { - -namespace { - -class ReferencedCursor -{ -public: - static ReferencedCursor find(const Cursor &cursor) - { - // Query the referenced cursor directly instead of first testing with cursor.isReference(). - // cursor.isReference() reports false for e.g. CXCursor_DeclRefExpr or CXCursor_CallExpr - // although it returns a valid cursor. - const Cursor referenced = cursor.referenced(); - if (referenced.isValid()) - return handleReferenced(referenced); - - const Cursor definition = cursor.definition(); - if (definition.isValid()) - return definition; - - return cursor; - } - - Utf8String usr() const - { - return cursor.unifiedSymbolResolution() + usrSuffix; - } - - bool isLocalVariable() const - { - return cursor.isLocalVariable(); - } - -private: - ReferencedCursor(const Cursor &cursor, const Utf8String &usrSuffix = Utf8String()) - : cursor(cursor) - , usrSuffix(usrSuffix) - {} - - static ReferencedCursor handleReferenced(const Cursor &cursor) - { - if (cursor.kind() == CXCursor_OverloadedDeclRef) { - // e.g. Text cursor is on "App" of "using N::App;". - if (cursor.overloadedDeclarationsCount() >= 1) - return cursor.overloadedDeclaration(0); - } - - if (cursor.isConstructorOrDestructor()) { - const Type type = cursor.type(); - if (type.isValid()) { - const Cursor typeDeclaration = type.declaration(); - if (typeDeclaration.isValid()) { - // A CXCursor_CallExpr like "new Foo" has a type of CXType_Record and its - // declaration is e.g. CXCursor_ClassDecl. - return typeDeclaration; - } else { - // A CXCursor_Constructor like "Foo();" has a type of CXType_FunctionProto - // and its type declaration is invalid, so use the semantic parent. - const Cursor parent = cursor.semanticParent(); - if (parent.isValid()) - return parent; - } - } - } - - if (cursor.isFunctionLike() || cursor.isTemplateLike()) { - const Cursor parent = cursor.semanticParent(); - const ClangString spelling = cursor.spelling(); - return {parent, Utf8StringLiteral("_qtc_") + Utf8String(spelling)}; - } - - return cursor; - } - -private: - Cursor cursor; - Utf8String usrSuffix; -}; - -class ReferencesCollector -{ -public: - ReferencesCollector(CXTranslationUnit cxTranslationUnit); - - ReferencesResult collect(uint line, uint column, bool localReferences = false) const; - -private: - bool pointsToIdentifier(int line, int column, unsigned *tokenIndex) const; - bool matchesIdentifier(const Token &token, const Utf8String &identifier) const; - bool checkToken(unsigned index, const Utf8String &identifier, const Utf8String &usr) const; - -private: - CXTranslationUnit m_cxTranslationUnit = nullptr; - Tokens m_tokens; - std::vector<Cursor> m_cursors; -}; - -ReferencesCollector::ReferencesCollector(CXTranslationUnit cxTranslationUnit) - : m_cxTranslationUnit(cxTranslationUnit) - , m_tokens(Cursor(clang_getTranslationUnitCursor(m_cxTranslationUnit)).sourceRange()) - , m_cursors(m_tokens.annotate()) -{ -} - -bool ReferencesCollector::pointsToIdentifier(int line, int column, unsigned *tokenIndex) const -{ - for (int i = 0; i < m_tokens.size(); ++i) { - const Token &token = m_tokens[i]; - if (token.kind() == CXToken_Identifier && token.extent().contains(line, column)) { - *tokenIndex = i; - return true; - } - } - - return false; -} - -bool ReferencesCollector::matchesIdentifier(const Token &token, - const Utf8String &identifier) const -{ - const CXTokenKind tokenKind = token.kind(); - if (tokenKind == CXToken_Identifier) - return token.spelling() == identifier; - - return false; -} - -bool ReferencesCollector::checkToken(unsigned index, const Utf8String &identifier, - const Utf8String &usr) const -{ - const Token &token = m_tokens[index]; - if (!matchesIdentifier(token, identifier)) - return false; - - { // For debugging only -// const SourceRange range{m_cxTranslationUnit, clang_getTokenExtent(m_cxTranslationUnit, token)}; -// const uint line = range.start().line(); -// const ClangString spellingCs = clang_getTokenSpelling(m_cxTranslationUnit, token); -// const Utf8String spelling = spellingCs; -// qWarning() << "ReferencesCollector::checkToken:" << line << spelling; - } - - const ReferencedCursor candidate = ReferencedCursor::find(m_cursors[index]); - - return candidate.usr() == usr; -} - -ReferencesResult ReferencesCollector::collect(uint line, uint column, bool localReferences) const -{ - ReferencesResult result; - - unsigned index = 0; - if (!pointsToIdentifier(line, column, &index)) - return result; - - const ReferencedCursor refCursor = ReferencedCursor::find(m_cursors[index]); - const Utf8String usr = refCursor.usr(); - if (usr.isEmpty()) - return result; - - if (localReferences && !refCursor.isLocalVariable()) - return result; - - const Token &token = m_tokens[index]; - const Utf8String identifier = token.spelling(); - for (int i = 0; i < m_tokens.size(); ++i) { - if (checkToken(i, identifier, usr)) - result.references.append(m_tokens[i].extent()); - } - - result.isLocalVariable = refCursor.isLocalVariable(); - - return result; -} - -} // anonymous namespace - -ReferencesResult collectReferences(CXTranslationUnit cxTranslationUnit, - uint line, - uint column, - bool localReferences) -{ - ReferencesCollector collector(cxTranslationUnit); - return collector.collect(line, column, localReferences); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangreferencescollector.h b/src/tools/clangbackend/source/clangreferencescollector.h deleted file mode 100644 index c467f8b090..0000000000 --- a/src/tools/clangbackend/source/clangreferencescollector.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <clangsupport/sourcerangecontainer.h> - -#include <QVector> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -class ReferencesResult -{ -public: - ReferencesResult() = default; - ReferencesResult(bool isLocalVariable, const QVector<SourceRangeContainer> &references) - : isLocalVariable(isLocalVariable) - , references(references) - {} - - bool operator==(const ReferencesResult &other) const - { - return isLocalVariable == other.isLocalVariable - && references == other.references; - } - - bool isLocalVariable = false; - QVector<SourceRangeContainer> references; -}; - -ReferencesResult collectReferences(CXTranslationUnit cxTranslationUnit, - uint line, - uint column, - bool localReferences = false); - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/clangrequestannotationsjob.cpp b/src/tools/clangbackend/source/clangrequestannotationsjob.cpp deleted file mode 100644 index 2ffec0157c..0000000000 --- a/src/tools/clangbackend/source/clangrequestannotationsjob.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangrequestannotationsjob.h" - -#include <clangsupport/annotationsmessage.h> -#include <clangsupport/clangsupportdebugutils.h> -#include <clangsupport/clangcodemodelclientinterface.h> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -IAsyncJob::AsyncPrepareResult RequestAnnotationsJob::prepareAsyncRun() -{ - const JobRequest jobRequest = context().jobRequest; - QTC_ASSERT(jobRequest.type == JobRequest::Type::RequestAnnotations, - return AsyncPrepareResult()); - QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); - - const TranslationUnit translationUnit = *m_translationUnit; - setRunner([translationUnit]() { - TIME_SCOPE_DURATION("RequestAnnotationsJobRunner"); - - RequestAnnotationsJob::AsyncResult asyncResult; - translationUnit.extractAnnotations(asyncResult.firstHeaderErrorDiagnostic, - asyncResult.diagnostics, - asyncResult.tokenInfos, - asyncResult.skippedSourceRanges); - return asyncResult; - }); - - return AsyncPrepareResult{translationUnit.id()}; -} - -void RequestAnnotationsJob::finalizeAsyncRun() -{ - if (context().isDocumentOpen()) { - const AsyncResult result = asyncResult(); - context().client->annotations(AnnotationsMessage(m_pinnedFileContainer, - result.diagnostics, - result.firstHeaderErrorDiagnostic, - result.tokenInfos, - result.skippedSourceRanges)); - } -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangrequestannotationsjob.h b/src/tools/clangbackend/source/clangrequestannotationsjob.h deleted file mode 100644 index c0693eb26e..0000000000 --- a/src/tools/clangbackend/source/clangrequestannotationsjob.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocumentjob.h" - -#include <clangsupport/diagnosticcontainer.h> -#include <clangsupport/tokeninfocontainer.h> -#include <clangsupport/sourcerangecontainer.h> - -namespace ClangBackEnd { - -struct RequestAnnotationsJobResult -{ - ClangBackEnd::DiagnosticContainer firstHeaderErrorDiagnostic; - QVector<ClangBackEnd::DiagnosticContainer> diagnostics; - QVector<TokenInfoContainer> tokenInfos; - QVector<SourceRangeContainer> skippedSourceRanges; -}; - -class RequestAnnotationsJob : public DocumentJob<RequestAnnotationsJobResult> -{ -public: - using AsyncResult = RequestAnnotationsJobResult; - - AsyncPrepareResult prepareAsyncRun() override; - void finalizeAsyncRun() override; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangrequestreferencesjob.cpp b/src/tools/clangbackend/source/clangrequestreferencesjob.cpp deleted file mode 100644 index cb2354ede3..0000000000 --- a/src/tools/clangbackend/source/clangrequestreferencesjob.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangrequestreferencesjob.h" - -#include <clangsupport/clangsupportdebugutils.h> -#include <clangsupport/referencesmessage.h> -#include <clangsupport/clangcodemodelclientinterface.h> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -IAsyncJob::AsyncPrepareResult RequestReferencesJob::prepareAsyncRun() -{ - const JobRequest jobRequest = context().jobRequest; - QTC_ASSERT(jobRequest.type == JobRequest::Type::RequestReferences, - return AsyncPrepareResult()); - QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); - - const TranslationUnit translationUnit = *m_translationUnit; - const quint32 line = jobRequest.line; - const quint32 column = jobRequest.column; - const bool localReferences = jobRequest.localReferences; - setRunner([translationUnit, line, column, localReferences]() { - TIME_SCOPE_DURATION("RequestReferencesJobRunner"); - return translationUnit.references(line, column, localReferences); - }); - - return AsyncPrepareResult{translationUnit.id()}; -} - -void RequestReferencesJob::finalizeAsyncRun() -{ - if (!context().isOutdated()) { - const AsyncResult result = asyncResult(); - - const ReferencesMessage message(m_pinnedFileContainer, - result.references, - result.isLocalVariable, - context().jobRequest.ticketNumber); - context().client->references(message); - } -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangrequestreferencesjob.h b/src/tools/clangbackend/source/clangrequestreferencesjob.h deleted file mode 100644 index d92d869a9b..0000000000 --- a/src/tools/clangbackend/source/clangrequestreferencesjob.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocumentjob.h" -#include "clangreferencescollector.h" - -namespace ClangBackEnd { - -class RequestReferencesJob : public DocumentJob<ReferencesResult> -{ -public: - using AsyncResult = ReferencesResult; - - AsyncPrepareResult prepareAsyncRun() override; - void finalizeAsyncRun() override; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangrequesttooltipjob.cpp b/src/tools/clangbackend/source/clangrequesttooltipjob.cpp deleted file mode 100644 index 0e1249e4e8..0000000000 --- a/src/tools/clangbackend/source/clangrequesttooltipjob.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangrequesttooltipjob.h" - -#include <clangsupport/clangsupportdebugutils.h> -#include <clangsupport/clangcodemodelclientinterface.h> -#include <clangsupport/tooltipmessage.h> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -IAsyncJob::AsyncPrepareResult RequestToolTipJob::prepareAsyncRun() -{ - const JobRequest jobRequest = context().jobRequest; - QTC_ASSERT(jobRequest.type == JobRequest::Type::RequestToolTip, return AsyncPrepareResult()); - QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); - - const TranslationUnit translationUnit = *m_translationUnit; - const UnsavedFiles unsavedFiles = *context().unsavedFiles; - const quint32 line = jobRequest.line; - const quint32 column = jobRequest.column; - const Utf8String textCodecName = jobRequest.textCodecName; - setRunner([translationUnit, unsavedFiles, line, column, textCodecName]() { - TIME_SCOPE_DURATION("RequestToolTipJobRunner"); - - UnsavedFiles theUnsavedFiles = unsavedFiles; - return translationUnit.tooltip(theUnsavedFiles, textCodecName, line, column); - }); - return AsyncPrepareResult{translationUnit.id()}; -} - -void RequestToolTipJob::finalizeAsyncRun() -{ - if (!context().isOutdated()) { - const AsyncResult result = asyncResult(); - - context().client->tooltip(ToolTipMessage(m_pinnedFileContainer, - result, - context().jobRequest.ticketNumber)); - } -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangrequesttooltipjob.h b/src/tools/clangbackend/source/clangrequesttooltipjob.h deleted file mode 100644 index eb121402cb..0000000000 --- a/src/tools/clangbackend/source/clangrequesttooltipjob.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <clangsupport/tooltipinfo.h> - -#include "clangdocumentjob.h" - -namespace ClangBackEnd { - -class RequestToolTipJob : public DocumentJob<ToolTipInfo> -{ -public: - using AsyncResult = ToolTipInfo; - - AsyncPrepareResult prepareAsyncRun() override; - void finalizeAsyncRun() override; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangresumedocumentjob.cpp b/src/tools/clangbackend/source/clangresumedocumentjob.cpp deleted file mode 100644 index 537472d66a..0000000000 --- a/src/tools/clangbackend/source/clangresumedocumentjob.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangresumedocumentjob.h" - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -void ResumeDocumentJob::finalizeAsyncRun() -{ - if (context().isDocumentOpen()) { - if (QTC_GUARD(asyncResult().updateResult.hasReparsed())) - m_pinnedDocument.setIsSuspended(false); - } - - UpdateAnnotationsJob::finalizeAsyncRun(); -} - -bool ResumeDocumentJob::isExpectedJobRequestType(const JobRequest &jobRequest) const -{ - return jobRequest.type == JobRequest::Type::ResumeDocument; -} - -TranslationUnitUpdateInput ResumeDocumentJob::createUpdateInput(const Document &document) const -{ - TranslationUnitUpdateInput input = UpdateAnnotationsJob::createUpdateInput(document); - input.reparseNeeded = true; - return input; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangresumedocumentjob.h b/src/tools/clangbackend/source/clangresumedocumentjob.h deleted file mode 100644 index 2d9c764e52..0000000000 --- a/src/tools/clangbackend/source/clangresumedocumentjob.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangasyncjob.h" -#include "clangdocument.h" -#include "clangupdateannotationsjob.h" - -namespace ClangBackEnd { - -class ResumeDocumentJob : public UpdateAnnotationsJob -{ -public: - void finalizeAsyncRun() override; - -private: - bool isExpectedJobRequestType(const JobRequest &jobRequest) const override; - TranslationUnitUpdateInput createUpdateInput(const Document &document) const override; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangstring.h b/src/tools/clangbackend/source/clangstring.h deleted file mode 100644 index cc70f548c4..0000000000 --- a/src/tools/clangbackend/source/clangstring.h +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <clang-c/CXString.h> - -#include <utf8string.h> - -#include <cstring> -#include <ostream> - -namespace ClangBackEnd { - -class ClangString -{ -public: - ClangString(CXString cxString) - : m_cxString(cxString) - { - } - - ~ClangString() - { - clang_disposeString(m_cxString); - } - - ClangString(const ClangString &) = delete; - const ClangString &operator=(const ClangString &) = delete; - - - ClangString(ClangString &&other) - : m_cxString(std::move(other.m_cxString)) - { - other.m_cxString.data = nullptr; - other.m_cxString.private_flags = 0; - } - - - ClangString &operator=(ClangString &&other) - { - if (this != &other) { - clang_disposeString(m_cxString); - m_cxString = std::move(other.m_cxString); - other.m_cxString.data = nullptr; - other.m_cxString.private_flags = 0; - } - - return *this; - } - - const char *cString() const - { - return clang_getCString(m_cxString); - } - - operator Utf8String() const - { - return Utf8String(cString(), -1); - } - - bool isNull() const - { - return m_cxString.data == nullptr; - } - - bool hasContent() const - { - return !isNull() && std::strlen(cString()) > 0; - } - - bool startsWith(const char* str) const - { - return std::strncmp(cString(), str, strlen(str)) == 0; - } - - friend bool operator==(const ClangString &first, const ClangString &second) - { - return std::strcmp(first.cString(), second.cString()) == 0; - } - - template<std::size_t Size> - friend bool operator==(const ClangString &first, const char(&second)[Size]) - { - return std::strncmp(first.cString(), second, Size) == 0; // Size includes \0 - } - - template<std::size_t Size> - friend bool operator==(const char(&first)[Size], const ClangString &second) - { - return second == first; - } - - template<typename Type, - typename = typename std::enable_if<std::is_pointer<Type>::value>::type - > - friend bool operator==(const ClangString &first, Type second) - { - return std::strcmp(first.cString(), second) == 0; - } - - template<typename Type, - typename = typename std::enable_if<std::is_pointer<Type>::value>::type - > - friend bool operator==(Type first, const ClangString &second) - { - return second == first; - } - - friend bool operator!=(const ClangString &first, const ClangString &second) - { - return !(first == second); - } - - template<std::size_t Size> - friend bool operator!=(const ClangString &first, const char(&second)[Size]) - { - return !(first == second); - } - - template<std::size_t Size> - friend bool operator!=(const char(&first)[Size], const ClangString &second) - { - return second != first; - } - - template<typename Type, - typename = typename std::enable_if<std::is_pointer<Type>::value>::type - > - friend bool operator!=(const ClangString &first, Type second) - { - return !(first == second); - } - - template<typename Type, - typename = typename std::enable_if<std::is_pointer<Type>::value>::type - > - friend bool operator!=(Type first, const ClangString &second) - { - return !(first == second); - } - - friend std::ostream &operator<<(std::ostream &os, const ClangString &string) - { - return os << string.cString(); - } - -private: - CXString m_cxString; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.cpp b/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.cpp deleted file mode 100644 index a34b7bb114..0000000000 --- a/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangsupportivetranslationunitinitializer.h" - -#include "clangjobs.h" -#include "clangtranslationunits.h" - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -SupportiveTranslationUnitInitializer::SupportiveTranslationUnitInitializer( - const Document &document, - Jobs &jobs) - : m_document(document) - , m_jobs(jobs) -{ -} - -void SupportiveTranslationUnitInitializer::setIsDocumentClosedChecker( - const IsDocumentClosedChecker &isDocumentClosedChecker) -{ - m_isDocumentClosedChecker = isDocumentClosedChecker; -} - -SupportiveTranslationUnitInitializer::State SupportiveTranslationUnitInitializer::state() const -{ - return m_state; -} - -void SupportiveTranslationUnitInitializer::startInitializing() -{ - if (!checkStateAndDocument(State::NotInitialized)) - return; - - m_document.translationUnits().createAndAppend(); - - m_jobs.setJobFinishedCallback([this](const Jobs::RunningJob &runningJob, IAsyncJob *) { - checkIfParseJobFinished(runningJob); - return false; - }); - addJob(JobRequest::Type::ParseSupportiveTranslationUnit); - m_jobs.process(); - - m_state = State::WaitingForParseJob; -} - -void SupportiveTranslationUnitInitializer::abort() -{ - if (m_document.translationUnits().size() > 1) - m_jobs.setJobFinishedCallback(Jobs::JobFinishedCallback()); - m_state = State::Aborted; -} - -void SupportiveTranslationUnitInitializer::checkIfParseJobFinished(const Jobs::RunningJob &job) -{ - if (!checkStateAndDocument(State::WaitingForParseJob)) - return; - - if (job.jobRequest.type == JobRequest::Type::ParseSupportiveTranslationUnit) { - if (m_document.translationUnits().areAllTranslationUnitsParsed()) { - m_jobs.setJobFinishedCallback(nullptr); - m_state = State::Initialized; - } else { - // The supportive translation unit was parsed, but the document - // revision changed in the meanwhile, so try again. - addJob(JobRequest::Type::ParseSupportiveTranslationUnit); - } - } -} - -bool SupportiveTranslationUnitInitializer::checkStateAndDocument(State currentExpectedState) -{ - if (m_state != currentExpectedState) { - m_state = State::Aborted; - return false; - } - - QTC_CHECK(m_isDocumentClosedChecker); - if (m_isDocumentClosedChecker(m_document.filePath())) { - m_state = State::Aborted; - return false; - } - - return true; -} - -void SupportiveTranslationUnitInitializer::addJob(JobRequest::Type jobRequestType) -{ - const JobRequest jobRequest = m_jobs.createJobRequest( - m_document, jobRequestType, PreferredTranslationUnit::LastUninitialized); - - m_jobs.add(jobRequest); -} - -void SupportiveTranslationUnitInitializer::setState(const State &state) -{ - m_state = state; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.h b/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.h deleted file mode 100644 index 4476bcf4ef..0000000000 --- a/src/tools/clangbackend/source/clangsupportivetranslationunitinitializer.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangdocument.h" -#include "clangjobs.h" - -#include <functional> - -#pragma once - -namespace ClangBackEnd { - -class SupportiveTranslationUnitInitializer -{ -public: - using IsDocumentClosedChecker = std::function<bool(const Utf8String &)>; - - enum class State { - NotInitialized, - WaitingForParseJob, - Initialized, - Aborted - }; - -public: - SupportiveTranslationUnitInitializer(const Document &document, Jobs &jobs); - - void setIsDocumentClosedChecker(const IsDocumentClosedChecker &isDocumentClosedChecker); - - State state() const; - void startInitializing(); - void abort(); - -public: // for tests - void setState(const State &state); - void checkIfParseJobFinished(const Jobs::RunningJob &job); - -private: - bool checkStateAndDocument(State currentExpectedState); - void addJob(JobRequest::Type jobRequestType); - -private: - Document m_document; - Jobs &m_jobs; - - State m_state = State::NotInitialized; - IsDocumentClosedChecker m_isDocumentClosedChecker; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangsuspenddocumentjob.cpp b/src/tools/clangbackend/source/clangsuspenddocumentjob.cpp deleted file mode 100644 index 87fe54bfae..0000000000 --- a/src/tools/clangbackend/source/clangsuspenddocumentjob.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangsuspenddocumentjob.h" - -#include <clangsupport/clangsupportdebugutils.h> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -IAsyncJob::AsyncPrepareResult SuspendDocumentJob::prepareAsyncRun() -{ - const JobRequest jobRequest = context().jobRequest; - QTC_ASSERT(jobRequest.type == JobRequest::Type::SuspendDocument, return AsyncPrepareResult()); - QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); - - TranslationUnit translationUnit = *m_translationUnit; - setRunner([translationUnit]() { - TIME_SCOPE_DURATION("SuspendDocumentJobRunner"); - return translationUnit.suspend(); - }); - - return AsyncPrepareResult{translationUnit.id()}; -} - -void SuspendDocumentJob::finalizeAsyncRun() -{ - if (context().isDocumentOpen()) { - const bool suspendSucceeded = asyncResult(); - if (QTC_GUARD(suspendSucceeded)) { - m_pinnedDocument.setIsSuspended(true); - } - } -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangsuspenddocumentjob.h b/src/tools/clangbackend/source/clangsuspenddocumentjob.h deleted file mode 100644 index 5948f8226f..0000000000 --- a/src/tools/clangbackend/source/clangsuspenddocumentjob.h +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocumentjob.h" - -namespace ClangBackEnd { - -class SuspendDocumentJob : public DocumentJob<bool> -{ -public: - AsyncPrepareResult prepareAsyncRun() override; - void finalizeAsyncRun() override; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangtooltipinfocollector.cpp b/src/tools/clangbackend/source/clangtooltipinfocollector.cpp deleted file mode 100644 index 03a328915e..0000000000 --- a/src/tools/clangbackend/source/clangtooltipinfocollector.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangtooltipinfocollector.h" - -#include "clangbackend_global.h" -#include "clangstring.h" -#include "cursor.h" -#include "sourcerange.h" -#include "token.h" -#include "unsavedfiles.h" -#include "unsavedfile.h" - -#include <clangsupport/sourcerangecontainer.h> -#include <utils/fileutils.h> -#include <utils/qtcassert.h> -#include <utils/qtcassert.h> -#include <utils/textfileformat.h> - -#include <utf8string.h> - -#include <QDebug> -#include <QDir> -#include <QTextCodec> - -namespace ClangBackEnd { - -Utf8String qualificationPrefix(const Cursor &cursor) -{ - // TODO: Implement with qualificationPrefixAsVector() - Utf8String qualifiedName; - - for (Cursor parent = cursor.semanticParent(); - parent.isValid() && (parent.kind() == CXCursor_Namespace); - parent = parent.semanticParent()) { - qualifiedName = parent.spelling() + Utf8StringLiteral("::") + qualifiedName; - } - - return qualifiedName; -} - -namespace { - -Utf8StringVector qualificationPrefixAsVector(const Cursor &cursor) -{ - Utf8StringVector result; - - for (Cursor parent = cursor.semanticParent(); - parent.isValid() && (parent.kind() == CXCursor_Namespace || parent.isCompoundType()); - parent = parent.semanticParent()) { - result.prepend(parent.spelling()); - } - - return result; -} - -Utf8String displayName(const Cursor &cursor) -{ - if (cursor.kind() == CXCursor_ClassTemplate) { - // TODO: The qualification should be part of the display name. Fix this in libclang. - return qualificationPrefix(cursor) + cursor.displayName(); - } - - return cursor.displayName(); -} - -Utf8String textForFunctionLike(const Cursor &cursor) -{ - CXPrintingPolicy policy = clang_getCursorPrintingPolicy(cursor.cx()); - clang_PrintingPolicy_setProperty(policy, CXPrintingPolicy_FullyQualifiedName, 1); - clang_PrintingPolicy_setProperty(policy, CXPrintingPolicy_TerseOutput, 1); - // Avoid printing attributes/pragmas - clang_PrintingPolicy_setProperty(policy, CXPrintingPolicy_PolishForDeclaration, 1); - clang_PrintingPolicy_setProperty(policy, CXPrintingPolicy_SuppressInitializers, 1); - const Utf8String prettyPrinted = ClangString( - clang_getCursorPrettyPrinted(cursor.cx(), policy)); - clang_PrintingPolicy_dispose(policy); - return prettyPrinted; -} - -Utf8String textForEnumConstantDecl(const Cursor &cursor) -{ - const Cursor semanticParent = cursor.semanticParent(); - QTC_ASSERT(semanticParent.kind() == CXCursor_EnumDecl, return Utf8String()); - - const Type enumType = semanticParent.enumType(); - if (enumType.isUnsigned()) - return Utf8String::number(cursor.enumConstantUnsignedValue()); - return Utf8String::number(cursor.enumConstantValue()); -} - -Utf8String textForInclusionDirective(const Cursor &cursor) -{ - const CXFile includedFile = cursor.includedFile(); - const Utf8String fileName = ClangString(clang_getFileName(includedFile)); - - return QDir::toNativeSeparators(fileName.toString()); -} - -Utf8String textForAnyTypeAlias(const Cursor &cursor) -{ - // For a CXCursor_TypeAliasTemplateDecl the type of cursor/referenced - // is invalid, so we do not get the underlying type. This here solely - // reports the unresolved name instead of the empty string. - if (cursor.kind() == CXCursor_TypeAliasTemplateDecl) - return cursor.displayName(); - - return cursor.type().alias().utf8Spelling(); -} - -bool includeSizeForCursor(const Cursor &cursor) -{ - return cursor.isCompoundType() - || cursor.kind() == CXCursor_EnumDecl - || cursor.kind() == CXCursor_UnionDecl - || cursor.kind() == CXCursor_FieldDecl; -} - -Utf8String sizeInBytes(const Cursor &cursor) -{ - if (includeSizeForCursor(cursor)) { - bool ok = false; - const long long size = cursor.type().sizeOf(&ok); - if (ok) - return Utf8String::number(size); - } - - return Utf8String(); -} - -QVariant value(const Cursor &cursor) -{ - if (!clang_isDeclaration(cursor.cx().kind) && !clang_isExpression(cursor.cx().kind)) - return {}; - const CXEvalResult evalResult = clang_Cursor_Evaluate(cursor.cx()); - QVariant v; - switch (clang_EvalResult_getKind(evalResult)) { - case CXEval_Int: - v = clang_EvalResult_isUnsignedInt(evalResult) - ? QVariant::fromValue(clang_EvalResult_getAsUnsigned(evalResult)) - : QVariant::fromValue(clang_EvalResult_getAsLongLong(evalResult)); - break; - case CXEval_Float: - v = QVariant::fromValue(clang_EvalResult_getAsDouble(evalResult)); - break; - default: - break; - } - clang_EvalResult_dispose(evalResult); - return v; -} - -Cursor referencedCursor(const Cursor &cursor) -{ - // Query the referenced cursor directly instead of first testing with cursor.isReference(). - // cursor.isReference() reports false for e.g. CXCursor_DeclRefExpr or CXCursor_CallExpr - // although it returns a valid cursor. - const Cursor referenced = cursor.referenced(); - if (referenced.isValid()) - return referenced; - - const Cursor definition = cursor.definition(); - if (definition.isValid()) - return definition; - - return cursor; -} - -class ToolTipInfoCollector -{ -public: - ToolTipInfoCollector(UnsavedFiles &unsavedFiles, - const Utf8String &textCodecName, - const Utf8String &mainFilePath, - CXTranslationUnit cxTranslationUnit); - - ToolTipInfo collect(uint line, uint column) const; - -private: - Utf8String text(const Cursor &cursor, const Cursor &referenced) const; - Utf8String textForMacroExpansion(const Cursor &cursor) const; - Utf8String textForNamespaceAlias(const Cursor &cursor) const; - - ToolTipInfo qDocInfo(const Cursor &cursor) const; - - CXSourceLocation toCXSourceLocation(uint line, uint column) const; - - UnsavedFile unsavedFile(const Utf8String &filePath) const; - Utf8String lineRange(const Utf8String &filePath, unsigned fromLine, unsigned toLine) const; - -private: - UnsavedFiles &m_unsavedFiles; - const Utf8String m_textCodecName; - - const Utf8String m_mainFilePath; - CXTranslationUnit m_cxTranslationUnit = nullptr; - -}; - -ToolTipInfoCollector::ToolTipInfoCollector(UnsavedFiles &unsavedFiles, - const Utf8String &textCodecName, - const Utf8String &mainFilePath, - CXTranslationUnit cxTranslationUnit) - : m_unsavedFiles(unsavedFiles) - , m_textCodecName(textCodecName) - , m_mainFilePath(mainFilePath) - , m_cxTranslationUnit(cxTranslationUnit) -{ -} - -Utf8String ToolTipInfoCollector::text(const Cursor &cursor, const Cursor &referenced) const -{ - if (cursor.kind() == CXCursor_MacroExpansion) - return textForMacroExpansion(referenced); - - if (referenced.kind() == CXCursor_EnumConstantDecl) - return textForEnumConstantDecl(referenced); - - if (referenced.kind() == CXCursor_InclusionDirective) - return textForInclusionDirective(referenced); - - if (referenced.kind() == CXCursor_Namespace) - return qualificationPrefix(referenced) + referenced.spelling(); - - if (referenced.kind() == CXCursor_NamespaceAlias) - return textForNamespaceAlias(referenced); - - if (referenced.isAnyTypeAlias()) - return textForAnyTypeAlias(referenced); - - if (referenced.isFunctionLike() || referenced.kind() == CXCursor_Constructor) - return textForFunctionLike(referenced); - - if (referenced.kind() == CXCursor_VarDecl) - return referenced.type().spelling(); // e.g. "Zii<int>" - - const Type referencedType = referenced.type(); - if (referencedType.isValid()) { - // Generally, the type includes the qualification but has this limitations: - // * namespace aliases are not resolved - // * outer class of a inner template class is not included - // The type includes the qualification, but not resolved namespace aliases. - - // For a CXType_Record, this also includes e.g. "const " as prefix. - return referencedType.canonical().utf8Spelling(); - } - - return displayName(referenced); -} - -Utf8String ToolTipInfoCollector::textForMacroExpansion(const Cursor &cursor) const -{ - QTC_ASSERT(cursor.kind() == CXCursor_MacroDefinition, return Utf8String()); - - const SourceRange sourceRange = cursor.sourceRange(); - const SourceLocation start = sourceRange.start(); - const SourceLocation end = sourceRange.end(); - - return lineRange(start.filePath(), start.line(), end.line()); -} - -Utf8String ToolTipInfoCollector::textForNamespaceAlias(const Cursor &cursor) const -{ - // TODO: Add some libclang API to get the aliased name straight away. - - const Tokens tokens(cursor.sourceRange()); - - Utf8String aliasedName; - // Start at 3 in order to skip these tokens: namespace X = - for (int i = 3; i < tokens.size(); ++i) - aliasedName += tokens[i].spelling(); - - return aliasedName; -} - -static Utf8String typeName(const Type &type) -{ - return type.declaration().spelling(); -} - -static Utf8String qdocMark(const Cursor &cursor) -{ - if (cursor.kind() == CXCursor_ClassTemplate) - return cursor.spelling(); - - if (cursor.type().kind() == CXType_Enum - || cursor.type().kind() == CXType_Typedef - || cursor.type().kind() == CXType_Record) - return typeName(cursor.type()); - - Utf8String text = cursor.displayName(); - if (cursor.kind() == CXCursor_FunctionDecl) { - // TODO: Remove this workaround by fixing this in - // libclang with the help of CXPrintingPolicy. - text.replace(Utf8StringLiteral("<>"), Utf8String()); - } - - return text; -} - -static ToolTipInfo::QdocCategory qdocCategory(const Cursor &cursor) -{ - if (cursor.isFunctionLike()) - return ToolTipInfo::Function; - - if (cursor.kind() == CXCursor_MacroDefinition) - return ToolTipInfo::Macro; - - if (cursor.kind() == CXCursor_EnumConstantDecl) - return ToolTipInfo::Enum; - - if (cursor.type().kind() == CXType_Enum) - return ToolTipInfo::Enum; - - if (cursor.kind() == CXCursor_InclusionDirective) - return ToolTipInfo::Brief; - - // TODO: Handle CXCursor_NamespaceAlias, too?! - if (cursor.kind() == CXCursor_Namespace) - return ToolTipInfo::ClassOrNamespace; - - if (cursor.isCompoundType()) - return ToolTipInfo::ClassOrNamespace; - - if (cursor.kind() == CXCursor_NamespaceAlias) - return ToolTipInfo::ClassOrNamespace; - - if (cursor.type().kind() == CXType_Typedef) - return ToolTipInfo::Typedef; - - if (cursor.type().kind() == CXType_Record) - return ToolTipInfo::ClassOrNamespace; - - if (cursor.kind() == CXCursor_TypeAliasTemplateDecl) - return ToolTipInfo::Typedef; - - if (cursor.kind() == CXCursor_ClassTemplate) - return ToolTipInfo::ClassOrNamespace; - - return ToolTipInfo::Unknown; -} - -static Utf8String name(const Cursor &cursor) -{ - if (cursor.type().kind() == CXType_Record || cursor.kind() == CXCursor_EnumDecl) - return typeName(cursor.type()); - - return cursor.spelling(); -} - -static Utf8StringVector qDocIdCandidates(const Cursor &cursor) -{ - Utf8StringVector components = qualificationPrefixAsVector(cursor); - if (components.isEmpty()) - return { name(cursor) }; - - components << name(cursor); - Utf8StringVector result; - Utf8String name; - for (auto it = components.rbegin(); it != components.rend(); ++it) { - if (name.isEmpty()) - name = *it; - else - name = *it + (Utf8StringLiteral("::") + name); - - result.prepend(name); - } - - return result; -} - -// TODO: Add libclang API for this?! -static bool isBuiltinOrPointerToBuiltin(const Type &type) -{ - Type theType = type; - - if (theType.isBuiltinType()) - return true; - - // TODO: Simplify - // TODO: Test with ** - while (theType.pointeeType().isValid() && theType != theType.pointeeType()) { - theType = theType.pointeeType(); - if (theType.isBuiltinType()) - return true; - } - - return false; -} - -ToolTipInfo ToolTipInfoCollector::qDocInfo(const Cursor &cursor) const -{ - ToolTipInfo result; - - if (isBuiltinOrPointerToBuiltin(cursor.type())) - return result; - - if (cursor.kind() == CXCursor_Constructor) { - const ToolTipInfo parentInfo = qDocInfo(cursor.semanticParent()); - result.qdocIdCandidates = parentInfo.qdocIdCandidates; - result.qdocMark = parentInfo.qdocMark; - result.qdocCategory = ToolTipInfo::Unknown; - return result; - } - - result.qdocIdCandidates = qDocIdCandidates(cursor); - result.qdocMark = qdocMark(cursor); - result.qdocCategory = qdocCategory(cursor); - - if (cursor.type().kind() == CXType_Record) { - result.qdocIdCandidates = qDocIdCandidates(cursor.type().declaration()); - return result; - } - - if (cursor.kind() == CXCursor_VarDecl || cursor.kind() == CXCursor_ParmDecl - || cursor.kind() == CXCursor_FieldDecl) { - // maybe template instantiation - if (cursor.type().kind() == CXType_Unexposed && cursor.type().canonical().kind() == CXType_Record) { - result.qdocIdCandidates = qDocIdCandidates(cursor.type().canonical().declaration()); - result.qdocMark = typeName(cursor.type()); - result.qdocCategory = ToolTipInfo::ClassOrNamespace; - return result; - } - - Type type = cursor.type(); - while (type.pointeeType().isValid() && type != type.pointeeType()) - type = type.pointeeType(); - - const Cursor typeCursor = type.declaration(); - result.qdocIdCandidates = qDocIdCandidates(typeCursor); - result.qdocCategory = qdocCategory(typeCursor); - result.qdocMark = typeName(type); - } - - // TODO: Handle also RValueReference() - if (cursor.type().isLValueReference()) { - const Cursor pointeeTypeDeclaration = cursor.type().pointeeType().declaration(); - result.qdocIdCandidates = qDocIdCandidates(pointeeTypeDeclaration); - result.qdocMark = pointeeTypeDeclaration.spelling(); - result.qdocCategory = qdocCategory(pointeeTypeDeclaration); - return result; - } - - return result; -} - -CXSourceLocation ToolTipInfoCollector::toCXSourceLocation(uint line, uint column) const -{ - return clang_getLocation(m_cxTranslationUnit, - clang_getFile(m_cxTranslationUnit, - m_mainFilePath.constData()), - line, - column); -} - -UnsavedFile ToolTipInfoCollector::unsavedFile(const Utf8String &filePath) const -{ - const UnsavedFile &unsavedFile = m_unsavedFiles.unsavedFile(filePath); - if (!unsavedFile.filePath().isEmpty()) - return unsavedFile; - - // Create an unsaved file with the file content from disk. - // TODO: Make use of clang_getFileContents() instead of reading from disk. - QTextCodec *codec = QTextCodec::codecForName(m_textCodecName); - QByteArray fileContent; - QString errorString; - using namespace Utils; - const TextFileFormat::ReadResult readResult - = TextFileFormat::readFileUTF8(Utils::FilePath::fromString(filePath), - codec, - &fileContent, - &errorString); - if (readResult != TextFileFormat::ReadSuccess) { - qWarning() << "Failed to read file" << filePath << ":" << errorString; - return UnsavedFile(); - } - - return UnsavedFile(filePath, Utf8String::fromByteArray(fileContent)); -} - -Utf8String ToolTipInfoCollector::lineRange(const Utf8String &filePath, - unsigned fromLine, - unsigned toLine) const -{ - if (toLine < fromLine) - return Utf8String(); - - const UnsavedFile file = unsavedFile(filePath); - if (file.fileContent().isEmpty()) - return Utf8String(); - - return file.lineRange(fromLine, toLine); -} - -ToolTipInfo ToolTipInfoCollector::collect(uint line, uint column) const -{ - Cursor cursor = clang_getCursor(m_cxTranslationUnit, toCXSourceLocation(line, column)); - if (!cursor.isValid()) { // QTCREATORBUG-21194 - Tokens tokens(Cursor(clang_getTranslationUnitCursor(m_cxTranslationUnit)).sourceRange()); - if (!tokens.size()) - return {}; - - // TODO: Only annotate the tokens up until the location we are interested in? - // Same goes for FollowSymbol. - const std::vector<Cursor> cursors = tokens.annotate(); - - const int tokenIndex = tokens.getTokenIndex(m_cxTranslationUnit, line, column); - QTC_ASSERT(tokenIndex >= 0, return {}); - const Utf8String tokenSpelling = tokens[tokenIndex].spelling(); - if (tokenSpelling.isEmpty()) - return {}; - cursor = cursors[tokenIndex]; - } - if (!cursor.isValid()) - return {}; - - const Cursor referenced = referencedCursor(cursor); - QTC_CHECK(referenced.isValid()); - - ToolTipInfo info; - info.text = text(cursor, referenced); - info.briefComment = referenced.briefComment(); - info.value = value(cursor); - - { - ToolTipInfo qDocToolTipInfo = qDocInfo(referenced); - info.qdocIdCandidates = qDocToolTipInfo.qdocIdCandidates; - info.qdocMark = qDocToolTipInfo.qdocMark; - info.qdocCategory = qDocToolTipInfo.qdocCategory; - } - - info.sizeInBytes = sizeInBytes(cursor); - - return info; -} - -} // anonymous namespace - -ToolTipInfo collectToolTipInfo(UnsavedFiles &unsavedFiles, - const Utf8String &textCodecName, - const Utf8String &mainFilePath, - CXTranslationUnit cxTranslationUnit, - uint line, - uint column) -{ - ToolTipInfoCollector collector(unsavedFiles, textCodecName, mainFilePath, cxTranslationUnit); - const ToolTipInfo info = collector.collect(line, column); - - return info; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangtooltipinfocollector.h b/src/tools/clangbackend/source/clangtooltipinfocollector.h deleted file mode 100644 index ae1609c276..0000000000 --- a/src/tools/clangbackend/source/clangtooltipinfocollector.h +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <utf8string.h> - -#include <clangsupport/tooltipinfo.h> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -class Cursor; -class UnsavedFiles; - -ToolTipInfo collectToolTipInfo(UnsavedFiles &unsavedFiles, - const Utf8String &textCodecName, - const Utf8String &mainFilePath, - CXTranslationUnit cxTranslationUnit, - uint line, - uint column); - -Utf8String qualificationPrefix(const Cursor &cursor); - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangtranslationunit.cpp b/src/tools/clangbackend/source/clangtranslationunit.cpp deleted file mode 100644 index cc848f89ab..0000000000 --- a/src/tools/clangbackend/source/clangtranslationunit.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangtranslationunit.h" - -#include "clangbackend_global.h" -#include "clangreferencescollector.h" -#include "clangtooltipinfocollector.h" -#include "clangtranslationunitupdater.h" -#include "clangfollowsymbol.h" -#include "clangfollowsymboljob.h" -#include "tokenprocessor.h" - -#include <codecompleter.h> -#include <cursor.h> -#include <diagnosticcontainer.h> -#include <diagnosticset.h> -#include <skippedsourceranges.h> -#include <sourcelocation.h> -#include <sourcerange.h> -#include <commandlinearguments.h> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -TranslationUnit::TranslationUnit(const Utf8String &id, - const Utf8String &filepath, - CXIndex &cxIndex, - CXTranslationUnit &cxTranslationUnit) - : m_id(id) - , m_filePath(filepath) - , m_cxIndex(cxIndex) - , m_cxTranslationUnit(cxTranslationUnit) -{ -} - -bool TranslationUnit::isNull() const -{ - return !m_cxTranslationUnit || !m_cxIndex || m_filePath.isEmpty() || m_id.isEmpty(); -} - -Utf8String TranslationUnit::id() const -{ - return m_id; -} - -Utf8String TranslationUnit::filePath() const -{ - return m_filePath; -} - -CXIndex &TranslationUnit::cxIndex() const -{ - return m_cxIndex; -} - -CXTranslationUnit &TranslationUnit::cxTranslationUnit() const -{ - return m_cxTranslationUnit; -} - -TranslationUnitUpdateResult TranslationUnit::update( - const TranslationUnitUpdateInput &parseInput) const -{ - TranslationUnitUpdater updater(id(), cxIndex(), cxTranslationUnit(), parseInput); - - return updater.update(TranslationUnitUpdater::UpdateMode::AsNeeded); -} - -TranslationUnitUpdateResult TranslationUnit::parse( - const TranslationUnitUpdateInput &parseInput) const -{ - TranslationUnitUpdater updater(id(), cxIndex(), cxTranslationUnit(), parseInput); - - return updater.update(TranslationUnitUpdater::UpdateMode::ParseIfNeeded); -} - -TranslationUnitUpdateResult TranslationUnit::reparse( - const TranslationUnitUpdateInput &parseInput) const -{ - TranslationUnitUpdater updater(id(), cxIndex(), cxTranslationUnit(), parseInput); - - return updater.update(TranslationUnitUpdater::UpdateMode::ForceReparse); -} - -bool TranslationUnit::suspend() const -{ - return clang_suspendTranslationUnit(cxTranslationUnit()); -} - -CodeCompletions TranslationUnit::complete(UnsavedFiles &unsavedFiles, uint line, uint column, - int funcNameStartLine, int funcNameStartColumn) const -{ - return CodeCompleter(*this, unsavedFiles).complete(line, column, funcNameStartLine, - funcNameStartColumn); -} - -void TranslationUnit::extractAnnotations( - DiagnosticContainer &firstHeaderErrorDiagnostic, - QVector<DiagnosticContainer> &mainFileDiagnostics, - QVector<TokenInfoContainer> &tokenInfos, - QVector<SourceRangeContainer> &skippedSourceRanges) const -{ - extractDiagnostics(firstHeaderErrorDiagnostic, mainFileDiagnostics); - tokenInfos = this->tokenInfos().toTokenInfoContainers(); - skippedSourceRanges = this->skippedSourceRanges().toSourceRangeContainers(); -} - -ToolTipInfo TranslationUnit::tooltip(UnsavedFiles &unsavedFiles, - const Utf8String &textCodecName, - uint line, - uint column) const -{ - return collectToolTipInfo(unsavedFiles, - textCodecName, - filePath(), - m_cxTranslationUnit, - line, - column); -} - -ReferencesResult TranslationUnit::references(uint line, uint column, bool localReferences) const -{ - return collectReferences(m_cxTranslationUnit, line, column, localReferences); -} - -DiagnosticSet TranslationUnit::diagnostics() const -{ - return DiagnosticSet(m_cxTranslationUnit, clang_getDiagnosticSetFromTU(m_cxTranslationUnit)); -} - -SourceLocation TranslationUnit::sourceLocationAt(uint line,uint column) const -{ - return SourceLocation(m_cxTranslationUnit, - clang_getLocation(m_cxTranslationUnit, - clang_getFile(m_cxTranslationUnit, - m_filePath.constData()), - line, column)); -} - -SourceLocation TranslationUnit::sourceLocationAt(const Utf8String &filePath, - uint line, - uint column) const -{ - return SourceLocation(m_cxTranslationUnit, - clang_getLocation(m_cxTranslationUnit, - clang_getFile(m_cxTranslationUnit, - filePath.constData()), - line, column)); -} - -SourceRange TranslationUnit::sourceRange(uint fromLine, - uint fromColumn, - uint toLine, - uint toColumn) const -{ - return SourceRange(sourceLocationAt(fromLine, fromColumn), - sourceLocationAt(toLine, toColumn)); -} - -Cursor TranslationUnit::cursorAt(uint line, uint column) const -{ - return clang_getCursor(m_cxTranslationUnit, sourceLocationAt(line, column)); -} - -Cursor TranslationUnit::cursorAt(const Utf8String &filePath, - uint line, - uint column) const -{ - return clang_getCursor(m_cxTranslationUnit, sourceLocationAt(filePath, line, column)); -} - -Cursor TranslationUnit::cursor() const -{ - return clang_getTranslationUnitCursor(m_cxTranslationUnit); -} - -TokenProcessor<TokenInfo> TranslationUnit::tokenInfos() const -{ - return tokenInfosInRange(cursor().sourceRange()); -} - -TokenProcessor<TokenInfo> TranslationUnit::tokenInfosInRange(const SourceRange &range) const -{ - return TokenProcessor<TokenInfo>(range); -} - -TokenProcessor<FullTokenInfo> TranslationUnit::fullTokenInfos() const -{ - return fullTokenInfosInRange(cursor().sourceRange()); -} - -TokenProcessor<FullTokenInfo> TranslationUnit::fullTokenInfosInRange(const SourceRange &range) const -{ - return TokenProcessor<FullTokenInfo>(range); -} - -SkippedSourceRanges TranslationUnit::skippedSourceRanges() const -{ - return SkippedSourceRanges(m_cxTranslationUnit, m_filePath.constData()); -} - -static bool isMainFileDiagnostic(const Utf8String &mainFilePath, const Diagnostic &diagnostic) -{ - return diagnostic.location().filePath() == mainFilePath; -} - -static bool isHeaderErrorDiagnostic(const Utf8String &mainFilePath, const Diagnostic &diagnostic) -{ - const bool isCritical = diagnostic.severity() == DiagnosticSeverity::Error - || diagnostic.severity() == DiagnosticSeverity::Fatal; - return isCritical && diagnostic.location().filePath() != mainFilePath; -} - -void TranslationUnit::extractDiagnostics(DiagnosticContainer &firstHeaderErrorDiagnostic, - QVector<DiagnosticContainer> &mainFileDiagnostics) const -{ - mainFileDiagnostics.clear(); - mainFileDiagnostics.reserve(int(diagnostics().size())); - - bool hasFirstHeaderErrorDiagnostic = false; - - for (const Diagnostic &diagnostic : diagnostics()) { - if (!hasFirstHeaderErrorDiagnostic && isHeaderErrorDiagnostic(m_filePath, diagnostic)) { - hasFirstHeaderErrorDiagnostic = true; - firstHeaderErrorDiagnostic = diagnostic.toDiagnosticContainer(); - } - - if (isMainFileDiagnostic(m_filePath, diagnostic)) - mainFileDiagnostics.push_back(diagnostic.toDiagnosticContainer()); - } -} - -FollowSymbolResult TranslationUnit::followSymbol(uint line, uint column) const -{ - return FollowSymbol::followSymbol(m_cxTranslationUnit, cursorAt(line, column), line, column); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangtranslationunit.h b/src/tools/clangbackend/source/clangtranslationunit.h deleted file mode 100644 index 83c8d196a6..0000000000 --- a/src/tools/clangbackend/source/clangtranslationunit.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "fulltokeninfo.h" -#include "tokenprocessor.h" - -#include <clangsupport/codecompletion.h> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -class Cursor; -class DiagnosticContainer; -class DiagnosticSet; -class FollowSymbolResult; -class ReferencesResult; -class SkippedSourceRanges; -class SourceLocation; -class SourceRange; -class SourceRangeContainer; -class ToolTipInfo; -class TranslationUnitUpdateInput; -class TranslationUnitUpdateResult; -class UnsavedFiles; -class CommandLineArguments; - -class TranslationUnit -{ -public: - TranslationUnit(const Utf8String &id, - const Utf8String &filePath, - CXIndex &cxIndex, - CXTranslationUnit &cxTranslationUnit); - - bool isNull() const; - - Utf8String id() const; - - Utf8String filePath() const; - CXIndex &cxIndex() const; - CXTranslationUnit &cxTranslationUnit() const; - - bool suspend() const; - - TranslationUnitUpdateResult update(const TranslationUnitUpdateInput &parseInput) const; - TranslationUnitUpdateResult parse(const TranslationUnitUpdateInput &parseInput) const; - TranslationUnitUpdateResult reparse(const TranslationUnitUpdateInput &parseInput) const; - - CodeCompletions complete(UnsavedFiles &unsavedFiles, uint line, uint column, - int funcNameStartLine, int funcNameStartColumn) const; - - void extractDiagnostics(DiagnosticContainer &firstHeaderErrorDiagnostic, - QVector<DiagnosticContainer> &mainFileDiagnostics) const; - void extractAnnotations(DiagnosticContainer &firstHeaderErrorDiagnostic, - QVector<DiagnosticContainer> &mainFileDiagnostics, - QVector<TokenInfoContainer> &tokenInfos, - QVector<SourceRangeContainer> &skippedSourceRanges) const; - - ReferencesResult references(uint line, uint column, bool localReferences = false) const; - ToolTipInfo tooltip(UnsavedFiles &unsavedFiles, - const Utf8String &textCodecName, - uint line, - uint column) const; - DiagnosticSet diagnostics() const; - - SourceLocation sourceLocationAt(uint line, uint column) const; - SourceLocation sourceLocationAt(const Utf8String &filePath, uint line, uint column) const; - SourceRange sourceRange(uint fromLine, uint fromColumn, uint toLine, uint toColumn) const; - - Cursor cursorAt(uint line, uint column) const; - Cursor cursorAt(const Utf8String &filePath, uint line, uint column) const; - Cursor cursor() const; - - TokenProcessor<TokenInfo> tokenInfos() const; - TokenProcessor<TokenInfo> tokenInfosInRange(const SourceRange &range) const; - - TokenProcessor<FullTokenInfo> fullTokenInfos() const; - TokenProcessor<FullTokenInfo> fullTokenInfosInRange(const SourceRange &range) const; - - SkippedSourceRanges skippedSourceRanges() const; - FollowSymbolResult followSymbol(uint line, uint column) const; - -private: - const Utf8String m_id; - const Utf8String m_filePath; - CXIndex &m_cxIndex; - CXTranslationUnit &m_cxTranslationUnit; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangtranslationunits.cpp b/src/tools/clangbackend/source/clangtranslationunits.cpp deleted file mode 100644 index 6175ea74a0..0000000000 --- a/src/tools/clangbackend/source/clangtranslationunits.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangtranslationunits.h" - -#include "clangexceptions.h" -#include "clangtranslationunit.h" - -#include <utils/algorithm.h> -#include <utils/qtcassert.h> - -#include <QFileInfo> -#include <QLoggingCategory> -#include <QUuid> - -static Q_LOGGING_CATEGORY(tuLog, "qtc.clangbackend.translationunits", QtWarningMsg); - -namespace ClangBackEnd { - -TranslationUnits::TranslationUnitData::TranslationUnitData(const Utf8String &id) - : id(id) -{} - -TranslationUnits::TranslationUnitData::~TranslationUnitData() -{ - qCDebug(tuLog) << "Destroying TranslationUnit" << id; - clang_disposeTranslationUnit(cxTranslationUnit); - clang_disposeIndex(cxIndex); -} - -TranslationUnits::TranslationUnits(const Utf8String &filePath) - : m_filePath(filePath) -{ -} - -TranslationUnit TranslationUnits::createAndAppend() -{ - const Utf8String id = Utf8String::fromByteArray(QUuid::createUuid().toByteArray()); - qCDebug(tuLog) << "Creating TranslationUnit" << id << "for" << QFileInfo(m_filePath).fileName(); - - m_units.append(TranslationUnitDataPtr(new TranslationUnitData(id))); - - return toTranslationUnit(m_units.last()); -} - -void TranslationUnits::removeAll() -{ - m_units.clear(); -} - -TranslationUnit TranslationUnits::get(PreferredTranslationUnit type) -{ - if (m_units.isEmpty()) - throw TranslationUnitDoesNotExist(m_filePath); - - if (m_units.size() == 1) - return toTranslationUnit(m_units.first()); - - if (areAllTranslationUnitsParsed()) - return getPreferredTranslationUnit(type); - - if (type == PreferredTranslationUnit::LastUninitialized) - return toTranslationUnit(m_units.last()); - - return toTranslationUnit(m_units.first()); -} - -void TranslationUnits::updateParseTimePoint(const Utf8String &translationUnitId, - TimePoint timePoint) -{ - QTC_CHECK(timePoint != TimePoint()); - - findUnit(translationUnitId).parseTimePoint = timePoint; - - qCDebug(tuLog) << "Updated" << translationUnitId << "for" << QFileInfo(m_filePath).fileName() - << "RecentlyParsed:" << get(PreferredTranslationUnit::RecentlyParsed).id() - << "PreviouslyParsed:" << get(PreferredTranslationUnit::PreviouslyParsed).id(); -} - -TimePoint TranslationUnits::parseTimePoint(const Utf8String &translationUnitId) -{ - return findUnit(translationUnitId).parseTimePoint; -} - -bool TranslationUnits::areAllTranslationUnitsParsed() const -{ - return Utils::allOf(m_units, [](const TranslationUnitDataPtr &unit) { - return unit->parseTimePoint != TimePoint(); - }); -} - -bool TranslationUnits::hasParsedTranslationUnit() const -{ - return Utils::anyOf(m_units, [](const TranslationUnitDataPtr &unit) { - return unit->parseTimePoint != TimePoint(); - }); -} - -int TranslationUnits::size() const -{ - return m_units.size(); -} - -TranslationUnit TranslationUnits::getPreferredTranslationUnit(PreferredTranslationUnit type) -{ - using TuDataPtr = TranslationUnitDataPtr; - - const auto lessThan = [](const TuDataPtr &a, const TuDataPtr &b) { - return a->parseTimePoint < b->parseTimePoint; - }; - auto it = type == PreferredTranslationUnit::RecentlyParsed - ? std::max_element(m_units.begin(), m_units.end(), lessThan) - : std::min_element(m_units.begin(), m_units.end(), lessThan); - - if (it == m_units.end()) - throw TranslationUnitDoesNotExist(m_filePath); - - return toTranslationUnit(*it); -} - -TranslationUnits::TranslationUnitData &TranslationUnits::findUnit( - const Utf8String &translationUnitId) -{ - for (TranslationUnitDataPtr &unit : m_units) { - if (translationUnitId == unit->id) - return *unit; - } - - throw TranslationUnitDoesNotExist(m_filePath); -} - -TranslationUnit TranslationUnits::toTranslationUnit(const TranslationUnitDataPtr &unit) -{ - return TranslationUnit(unit->id, - m_filePath, - unit->cxIndex, - unit->cxTranslationUnit); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangtranslationunits.h b/src/tools/clangbackend/source/clangtranslationunits.h deleted file mode 100644 index eed9b2d1ea..0000000000 --- a/src/tools/clangbackend/source/clangtranslationunits.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangbackend_global.h" -#include "clangclock.h" - -#include <utf8string.h> - -#include <clang-c/Index.h> - -#include <QList> -#include <QSharedPointer> - -namespace ClangBackEnd { - -class TranslationUnit; - -class TranslationUnits -{ -public: - class TranslationUnitData { - public: - TranslationUnitData(const Utf8String &id); - ~TranslationUnitData(); - - Utf8String id; - - CXTranslationUnit cxTranslationUnit = nullptr; - CXIndex cxIndex = nullptr; - - TimePoint parseTimePoint; - }; - using TranslationUnitDataPtr = QSharedPointer<TranslationUnitData>; - -public: - TranslationUnits(const Utf8String &filePath); - - TranslationUnit createAndAppend(); - void removeAll(); - TranslationUnit get(PreferredTranslationUnit type = PreferredTranslationUnit::RecentlyParsed); - void updateParseTimePoint(const Utf8String &translationUnitId, TimePoint timePoint); - - bool areAllTranslationUnitsParsed() const; - bool hasParsedTranslationUnit() const; - -public: // for tests - int size() const; - TimePoint parseTimePoint(const Utf8String &translationUnitId); - -private: - TranslationUnit getPreferredTranslationUnit(PreferredTranslationUnit type); - TranslationUnitData &findUnit(const Utf8String &translationUnitId); - TranslationUnit toTranslationUnit(const TranslationUnitDataPtr &unit); - -private: - Utf8String m_filePath; - QList<TranslationUnitDataPtr> m_units; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangtranslationunitupdater.cpp b/src/tools/clangbackend/source/clangtranslationunitupdater.cpp deleted file mode 100644 index 0383a1028f..0000000000 --- a/src/tools/clangbackend/source/clangtranslationunitupdater.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangtranslationunitupdater.h" - -#include "clangbackend_global.h" -#include "clangfilepath.h" -#include "clangstring.h" -#include "clangunsavedfilesshallowarguments.h" - -#include <QLoggingCategory> - -static Q_LOGGING_CATEGORY(verboseLibLog, "qtc.clangbackend.verboselib", QtWarningMsg); - -static bool isVerboseModeEnabled() -{ - return verboseLibLog().isDebugEnabled(); -} - -namespace ClangBackEnd { - -TranslationUnitUpdater::TranslationUnitUpdater(const Utf8String translationUnitId, - CXIndex &index, - CXTranslationUnit &cxTranslationUnit, - const TranslationUnitUpdateInput &updateData) - : m_cxIndex(index) - , m_cxTranslationUnit(cxTranslationUnit) - , m_in(updateData) -{ - m_out.translationUnitId = translationUnitId; -} - -TranslationUnitUpdateResult TranslationUnitUpdater::update(UpdateMode mode) -{ - createIndexIfNeeded(); - - switch (mode) { - case UpdateMode::AsNeeded: - recreateAndParseIfNeeded(); - reparseIfNeeded(); - break; - case UpdateMode::ParseIfNeeded: - recreateAndParseIfNeeded(); - break; - case UpdateMode::ForceReparse: - reparse(); - break; - } - - return m_out; -} - -void TranslationUnitUpdater::recreateAndParseIfNeeded() -{ - removeTranslationUnitIfProjectPartWasChanged(); - createTranslationUnitIfNeeded(); -} - -void TranslationUnitUpdater::removeTranslationUnitIfProjectPartWasChanged() -{ - if (m_in.parseNeeded) { - clang_disposeTranslationUnit(m_cxTranslationUnit); - m_cxTranslationUnit = nullptr; - } -} - -#define RETURN_TEXT_FOR_CASE(enumValue) case enumValue: return #enumValue -static const char *errorCodeToText(CXErrorCode errorCode) -{ - switch (errorCode) { - RETURN_TEXT_FOR_CASE(CXError_Success); - RETURN_TEXT_FOR_CASE(CXError_Failure); - RETURN_TEXT_FOR_CASE(CXError_Crashed); - RETURN_TEXT_FOR_CASE(CXError_InvalidArguments); - RETURN_TEXT_FOR_CASE(CXError_ASTReadError); - } - - return "UnknownCXErrorCode"; -} -#undef RETURN_TEXT_FOR_CASE - -void TranslationUnitUpdater::createTranslationUnitIfNeeded() -{ - if (!m_cxTranslationUnit) { - m_cxTranslationUnit = CXTranslationUnit(); - - const auto args = commandLineArguments(); - if (isVerboseModeEnabled()) - args.print(); - - UnsavedFilesShallowArguments unsaved = m_in.unsavedFiles.shallowArguments(); - - m_parseErrorCode = clang_parseTranslationUnit2(m_cxIndex, - nullptr, - args.data(), - args.count(), - unsaved.data(), - unsaved.count(), - defaultParseOptions(), - &m_cxTranslationUnit); - - - - if (parseWasSuccessful()) { - updateIncludeFilePaths(); - m_out.parseTimePoint = Clock::now(); - } else { - qWarning() << "Parsing" << m_in.filePath << "failed:" - << errorCodeToText(m_parseErrorCode); - m_out.hasParseOrReparseFailed = true; - } - } -} - -void TranslationUnitUpdater::reparseIfNeeded() -{ - if (m_in.reparseNeeded) - reparse(); -} - -void TranslationUnitUpdater::reparse() -{ - UnsavedFilesShallowArguments unsaved = m_in.unsavedFiles.shallowArguments(); - - m_reparseErrorCode = clang_reparseTranslationUnit( - m_cxTranslationUnit, - unsaved.count(), - unsaved.data(), - clang_defaultReparseOptions(m_cxTranslationUnit)); - - - if (reparseWasSuccessful()) { - updateIncludeFilePaths(); - - m_out.reparseTimePoint = Clock::now(); - m_out.needsToBeReparsedChangeTimePoint = m_in.needsToBeReparsedChangeTimePoint; - } else { - qWarning() << "Reparsing" << m_in.filePath << "failed:" << m_reparseErrorCode; - m_out.hasParseOrReparseFailed = true; - } -} - -void TranslationUnitUpdater::updateIncludeFilePaths() -{ - m_out.dependedOnFilePaths.clear(); - m_out.dependedOnFilePaths.insert(m_in.filePath); - - clang_getInclusions(m_cxTranslationUnit, - includeCallback, - const_cast<TranslationUnitUpdater *>(this)); -} - -uint TranslationUnitUpdater::defaultParseOptions() -{ - return CXTranslationUnit_CacheCompletionResults - | CXTranslationUnit_PrecompiledPreamble - | CXTranslationUnit_CreatePreambleOnFirstParse - | CXTranslationUnit_SkipFunctionBodies - | CXTranslationUnit_LimitSkipFunctionBodiesToPreamble -// CLANG-UPGRADE-CHECK: Remove when required version is 9 -#if (LLVM_VERSION_MAJOR >= 9) || defined(CINDEX_VERSION_HAS_SKIPWARNINGSFROMINCLUDEDFILES_BACKPORTED) - | CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles -#endif - | CXTranslationUnit_IncludeBriefCommentsInCodeCompletion - | CXTranslationUnit_DetailedPreprocessingRecord - | CXTranslationUnit_KeepGoing; -} - -void TranslationUnitUpdater::createIndexIfNeeded() -{ - if (!m_cxIndex) { - const bool displayDiagnostics = isVerboseModeEnabled(); - m_cxIndex = clang_createIndex(1, displayDiagnostics); - } -} - -void TranslationUnitUpdater::includeCallback(CXFile included_file, - CXSourceLocation *, - unsigned, CXClientData clientData) -{ - ClangString includeFilePath(clang_getFileName(included_file)); - - TranslationUnitUpdater *updater = static_cast<TranslationUnitUpdater *>(clientData); - - updater->m_out.dependedOnFilePaths.insert(FilePath::fromNativeSeparators(includeFilePath)); -} - -bool TranslationUnitUpdater::parseWasSuccessful() const -{ - return m_parseErrorCode == CXError_Success; -} - -bool TranslationUnitUpdater::reparseWasSuccessful() const -{ - return m_reparseErrorCode == 0; -} - -CommandLineArguments TranslationUnitUpdater::commandLineArguments() const -{ - return CommandLineArguments(m_in.filePath.constData(), - m_in.compilationArguments, - isVerboseModeEnabled()); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangtranslationunitupdater.h b/src/tools/clangbackend/source/clangtranslationunitupdater.h deleted file mode 100644 index a0f0d0ba3b..0000000000 --- a/src/tools/clangbackend/source/clangtranslationunitupdater.h +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangclock.h" - -#include "commandlinearguments.h" -#include "unsavedfiles.h" -#include "utf8stringvector.h" - -#include <clang-c/Index.h> - -#include <QSet> - -namespace ClangBackEnd { - -class TranslationUnitUpdateInput { -public: - bool parseNeeded = false; - bool reparseNeeded = false; - - TimePoint needsToBeReparsedChangeTimePoint; - - Utf8String filePath; - Utf8StringVector compilationArguments; - - UnsavedFiles unsavedFiles; -}; - -class TranslationUnitUpdateResult { -public: - bool hasParsed() const - { return parseTimePoint != TimePoint(); } - - bool hasReparsed() const - { return reparseTimePoint != TimePoint(); } - -public: - Utf8String translationUnitId; - - bool hasParseOrReparseFailed = false; - TimePoint parseTimePoint; - TimePoint reparseTimePoint; - TimePoint needsToBeReparsedChangeTimePoint; - - QSet<Utf8String> dependedOnFilePaths; -}; - -class TranslationUnitUpdater { -public: - enum class UpdateMode { - AsNeeded, - ParseIfNeeded, - ForceReparse, - }; - -public: - TranslationUnitUpdater(const Utf8String translationUnitId, - CXIndex &index, - CXTranslationUnit &cxTranslationUnit, - const TranslationUnitUpdateInput &in); - - TranslationUnitUpdateResult update(UpdateMode mode); - - CommandLineArguments commandLineArguments() const; - static uint defaultParseOptions(); - -private: - void createIndexIfNeeded(); - void createTranslationUnitIfNeeded(); - void removeTranslationUnitIfProjectPartWasChanged(); - void reparseIfNeeded(); - void recreateAndParseIfNeeded(); - void reparse(); - - void updateIncludeFilePaths(); - static void includeCallback(CXFile included_file, - CXSourceLocation *, - unsigned, - CXClientData clientData); - - bool parseWasSuccessful() const; - bool reparseWasSuccessful() const; - -private: - CXIndex &m_cxIndex; - CXTranslationUnit &m_cxTranslationUnit; - - CXErrorCode m_parseErrorCode = CXError_Success; - int m_reparseErrorCode = 0; - - const TranslationUnitUpdateInput m_in; - TranslationUnitUpdateResult m_out; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangtype.cpp b/src/tools/clangbackend/source/clangtype.cpp deleted file mode 100644 index 61b5d2bca8..0000000000 --- a/src/tools/clangbackend/source/clangtype.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangtype.h" - -#include "clangstring.h" -#include "cursor.h" - -#include <utf8string.h> - -#include <ostream> - -namespace ClangBackEnd { - -bool Type::isValid() const -{ - return m_cxType.kind != CXType_Invalid; -} - -bool Type::isConstant() const -{ - return clang_isConstQualifiedType(m_cxType); -} - -bool Type::isConstantReference() -{ - return isLValueReference() && pointeeType().isConstant(); -} - -bool Type::isPointer() const -{ - return m_cxType.kind == CXType_Pointer; -} - -bool Type::isPointerToConstant() const -{ - return isPointer() && pointeeType().isConstant(); -} - -bool Type::isConstantPointer() const -{ - return isPointer() && isConstant(); -} - -bool Type::isLValueReference() const -{ - return m_cxType.kind == CXType_LValueReference; -} - -bool Type::isReferencingConstant() const -{ - return (isPointer() || isLValueReference()) && pointeeType().isConstant(); -} - -bool Type::isOutputArgument() const -{ - if (isLValueReference() && !pointeeType().isConstant()) - return true; - - // We consider a pointer an output argument if it is non-const at any level. - // This is consistent with how we categorize references in CppEditor. - Type t = *this; - while (t.isPointer()) { - t = t.pointeeType(); - if (!t.isConstant()) - return true; - } - return false; -} - -bool Type::isBuiltinType() const -{ - return m_cxType.kind >= CXType_FirstBuiltin && m_cxType.kind <= CXType_LastBuiltin; -} - -bool Type::isUnsigned() const -{ - return m_cxType.kind == CXType_UChar - || m_cxType.kind == CXType_UShort - || m_cxType.kind == CXType_UInt - || m_cxType.kind == CXType_ULong - || m_cxType.kind == CXType_ULongLong - || m_cxType.kind == CXType_UInt128; -} - -Utf8String Type::utf8Spelling() const -{ - return ClangString(clang_getTypeSpelling(m_cxType)); -} - -ClangString Type::spelling() const -{ - return ClangString(clang_getTypeSpelling(m_cxType)); -} - -static const char *builtinTypeToText(CXTypeKind kind) -{ - // CLANG-UPGRADE-CHECK: Check for added built-in types. - - switch (kind) { - case CXType_Void: - return "void"; - case CXType_Bool: - return "bool"; - - // See also ${CLANG_REPOSITORY}/lib/Sema/SemaChecking.cpp - IsSameCharType(). - case CXType_Char_U: - case CXType_UChar: - return "unsigned char"; - case CXType_Char_S: - case CXType_SChar: - return "signed char"; - - case CXType_Char16: - return "char16_t"; - case CXType_Char32: - return "char32_t"; - case CXType_WChar: - return "wchar_t"; - - case CXType_UShort: - return "unsigned short"; - case CXType_UInt: - return "unsigned int"; - case CXType_ULong: - return "unsigned long"; - case CXType_ULongLong: - return "unsigned long long"; - case CXType_Short: - return "short"; - - case CXType_Int: - return "int"; - case CXType_Long: - return "long"; - case CXType_LongLong: - return "long long"; - - case CXType_Float: - return "float"; - case CXType_Double: - return "double"; - case CXType_LongDouble: - return "long double"; - - case CXType_NullPtr: - return "nullptr_t"; - - // https://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html - case CXType_Int128: return "__int128"; - case CXType_UInt128: return "unsigned __int128"; - - // https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html - case CXType_Float128: return "__float128"; - case CXType_Float16: return "_Float16"; - - // https://www.khronos.org/registry/OpenCL/sdk/2.1/docs/man/xhtml/scalarDataTypes.html - case CXType_Half: - return "half"; - - default: - return ""; - } -} - -Utf8String Type::builtinTypeToString() const -{ - const char *text = builtinTypeToText(m_cxType.kind); - return Utf8String::fromByteArray(QByteArray::fromRawData(text, int(strlen(text)))); -} - -int Type::argumentCount() const -{ - return clang_getNumArgTypes(m_cxType); -} - -Type Type::alias() const -{ - return clang_getTypedefDeclUnderlyingType(clang_getTypeDeclaration(m_cxType)); -} - -Type Type::canonical() const -{ - return clang_getCanonicalType(m_cxType); -} - -Type Type::classType() const -{ - return clang_Type_getClassType(m_cxType); -} - -Type Type::pointeeType() const -{ - return clang_getPointeeType(m_cxType); -} - -Type Type::resultType() const -{ - return clang_getResultType(m_cxType); -} - -Type Type::argument(int index) const -{ - return clang_getArgType(m_cxType, index); -} - -Cursor Type::declaration() const -{ - return clang_getTypeDeclaration(m_cxType); -} - -long long Type::sizeOf(bool *isValid) const -{ - const long long size = clang_Type_getSizeOf(m_cxType); - *isValid = size != CXTypeLayoutError_Invalid - && size != CXTypeLayoutError_Incomplete - && size != CXTypeLayoutError_Dependent; - - return size; -} - -CXTypeKind Type::kind() const -{ - return m_cxType.kind; -} - -Type::Type(CXType cxType) - : m_cxType(cxType) -{ -} - -bool operator==(Type first, Type second) -{ - return clang_equalTypes(first.m_cxType, second.m_cxType); -} - -bool operator!=(Type first, Type second) -{ - return !operator==(first, second); -} - -std::ostream &operator<<(std::ostream &os, CXTypeKind typeKind) -{ - ClangString typeKindSpelling(clang_getTypeKindSpelling(typeKind)); - - return os << typeKindSpelling.cString(); -} - -std::ostream &operator<<(std::ostream &os, const Type &type) -{ - ClangString typeKindSpelling(clang_getTypeKindSpelling(type.kind())); - os << typeKindSpelling - << ": \"" << type.spelling() << "\""; - - return os; -} - - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/clangtype.h b/src/tools/clangbackend/source/clangtype.h deleted file mode 100644 index c8dca274d9..0000000000 --- a/src/tools/clangbackend/source/clangtype.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <clang-c/Index.h> - -#include <iosfwd> - -class Utf8String; - -namespace ClangBackEnd { - -class Cursor; -class ClangString; - -class Type -{ - friend class Cursor; - friend bool operator==(Type first, Type second); - friend bool operator!=(Type first, Type second); - -public: - bool isValid() const; - - bool isConstant() const; - bool isConstantReference(); - bool isPointer() const; - bool isPointerToConstant() const; - bool isConstantPointer() const; - bool isLValueReference() const; - bool isReferencingConstant() const; - bool isOutputArgument() const; - bool isBuiltinType() const; - bool isUnsigned() const; - - Utf8String utf8Spelling() const; - ClangString spelling() const; - Utf8String builtinTypeToString() const; - int argumentCount() const; - - Type alias() const; - Type canonical() const; - Type classType() const; - Type pointeeType() const; - Type resultType() const; - Type argument(int index) const; - - Cursor declaration() const; - - long long sizeOf(bool *isValid) const; - - CXTypeKind kind() const; - -private: - Type(CXType cxType); - -private: - CXType m_cxType; -}; - -std::ostream &operator<<(std::ostream &os, CXTypeKind typeKind); -std::ostream &operator<<(std::ostream &os, const Type &type); -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangunsavedfilesshallowarguments.cpp b/src/tools/clangbackend/source/clangunsavedfilesshallowarguments.cpp deleted file mode 100644 index 6fe23d606f..0000000000 --- a/src/tools/clangbackend/source/clangunsavedfilesshallowarguments.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangunsavedfilesshallowarguments.h" -#include "clangfilepath.h" - -#include "unsavedfile.h" -#include "unsavedfiles.h" - -namespace ClangBackEnd { - -UnsavedFilesShallowArguments::UnsavedFilesShallowArguments(const UnsavedFiles &unsavedFiles) -{ - const int unsavedFilesCount = int(unsavedFiles.count()); - m_cxUnsavedFiles.resize(unsavedFilesCount); - - for (int i = 0, total = unsavedFilesCount; i < total; ++i) { - const UnsavedFile &unsavedFile = unsavedFiles.at(i); - m_cxUnsavedFiles[i].Filename = unsavedFile.nativeFilePath().constData(); - m_cxUnsavedFiles[i].Contents = unsavedFile.fileContent().constData(); - m_cxUnsavedFiles[i].Length = uint(unsavedFile.fileContent().byteSize()); - } -} - -uint UnsavedFilesShallowArguments::count() const -{ - return uint(m_cxUnsavedFiles.count()); -} - -CXUnsavedFile *UnsavedFilesShallowArguments::data() -{ - return m_cxUnsavedFiles.data(); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangunsavedfilesshallowarguments.h b/src/tools/clangbackend/source/clangunsavedfilesshallowarguments.h deleted file mode 100644 index 20c8981ef2..0000000000 --- a/src/tools/clangbackend/source/clangunsavedfilesshallowarguments.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <QVector> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -class UnsavedFile; -class UnsavedFiles; - -class UnsavedFilesShallowArguments { -public: - UnsavedFilesShallowArguments() = default; - UnsavedFilesShallowArguments(const UnsavedFiles &unsavedFiles); - - uint count() const; - CXUnsavedFile *data(); - -private: - QVector<CXUnsavedFile> m_cxUnsavedFiles; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangupdateannotationsjob.cpp b/src/tools/clangbackend/source/clangupdateannotationsjob.cpp deleted file mode 100644 index bdd05512e6..0000000000 --- a/src/tools/clangbackend/source/clangupdateannotationsjob.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangupdateannotationsjob.h" - -#include <clangsupport/annotationsmessage.h> -#include <clangsupport/clangsupportdebugutils.h> -#include <clangsupport/clangcodemodelclientinterface.h> - -#include <utils/qtcassert.h> - -#include <QRegularExpression> - -namespace ClangBackEnd { - -// TODO: Add libclang API for this. -static QSet<Utf8String> unresolvedFilePaths(const QVector<DiagnosticContainer> &diagnostics) -{ - // We expect something like: - // fatal error: 'ops.h' file not found - QRegularExpression re("'(.*)' file not found"); - QSet<Utf8String> unresolved; - - for (const DiagnosticContainer &diagnostic : diagnostics) { - if (diagnostic.severity == DiagnosticSeverity::Error - && diagnostic.category == Utf8StringLiteral("Lexical or Preprocessor Issue")) { - const QString path = re.match(diagnostic.text).captured(1); - if (!path.isEmpty()) - unresolved << path; - } - } - - return unresolved; -} - -IAsyncJob::AsyncPrepareResult UpdateAnnotationsJob::prepareAsyncRun() -{ - const JobRequest jobRequest = context().jobRequest; - QTC_ASSERT(isExpectedJobRequestType(jobRequest), return AsyncPrepareResult()); - QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); - - const TranslationUnit translationUnit = *m_translationUnit; - const TranslationUnitUpdateInput updateInput = createUpdateInput(m_pinnedDocument); - setRunner([translationUnit, updateInput]() { - TIME_SCOPE_DURATION("UpdateAnnotationsJobRunner"); - - // Update - UpdateAnnotationsJob::AsyncResult asyncResult; - asyncResult.updateResult = translationUnit.update(updateInput); - - // Collect - translationUnit.extractAnnotations(asyncResult.firstHeaderErrorDiagnostic, - asyncResult.diagnostics, - asyncResult.tokenInfos, - asyncResult.skippedSourceRanges); - asyncResult.unresolvedFilePaths.unite( - unresolvedFilePaths({asyncResult.firstHeaderErrorDiagnostic})); - asyncResult.unresolvedFilePaths.unite(unresolvedFilePaths(asyncResult.diagnostics)); - - return asyncResult; - }); - - return AsyncPrepareResult{translationUnit.id()}; -} - -void UpdateAnnotationsJob::finalizeAsyncRun() -{ - if (!context().isOutdated()) { - const AsyncResult result = asyncResult(); - - m_pinnedDocument.incorporateUpdaterResult(result.updateResult); - m_pinnedDocument.setUnresolvedFilePaths(result.unresolvedFilePaths); - - context().client->annotations(AnnotationsMessage(m_pinnedFileContainer, - result.diagnostics, - result.firstHeaderErrorDiagnostic, - result.tokenInfos, - result.skippedSourceRanges)); - } -} - -bool UpdateAnnotationsJob::isExpectedJobRequestType(const JobRequest &jobRequest) const -{ - return jobRequest.type == JobRequest::Type::UpdateAnnotations; -} - -TranslationUnitUpdateInput -UpdateAnnotationsJob::createUpdateInput(const Document &document) const -{ - return document.createUpdateInput(); -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/clangupdateannotationsjob.h b/src/tools/clangbackend/source/clangupdateannotationsjob.h deleted file mode 100644 index 8a813586ea..0000000000 --- a/src/tools/clangbackend/source/clangupdateannotationsjob.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocumentjob.h" - -#include <clangsupport/diagnosticcontainer.h> -#include <clangsupport/tokeninfocontainer.h> -#include <clangsupport/sourcerangecontainer.h> - -#include <QSet> -#include <QVector> - -namespace ClangBackEnd { - -struct UpdateAnnotationsJobResult -{ - TranslationUnitUpdateResult updateResult; - QSet<Utf8String> unresolvedFilePaths; - - ClangBackEnd::DiagnosticContainer firstHeaderErrorDiagnostic; - QVector<ClangBackEnd::DiagnosticContainer> diagnostics; - QVector<TokenInfoContainer> tokenInfos; - QVector<SourceRangeContainer> skippedSourceRanges; -}; - -class UpdateAnnotationsJob : public DocumentJob<UpdateAnnotationsJobResult> -{ -public: - using AsyncResult = UpdateAnnotationsJobResult; - - AsyncPrepareResult prepareAsyncRun() override; - void finalizeAsyncRun() override; - -protected: - virtual bool isExpectedJobRequestType(const JobRequest &jobRequest) const; - virtual TranslationUnitUpdateInput createUpdateInput(const Document &document) const; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangupdateextraannotationsjob.cpp b/src/tools/clangbackend/source/clangupdateextraannotationsjob.cpp deleted file mode 100644 index 7363a28758..0000000000 --- a/src/tools/clangbackend/source/clangupdateextraannotationsjob.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangupdateextraannotationsjob.h" - -#include <clangsupport/annotationsmessage.h> -#include <clangsupport/clangsupportdebugutils.h> -#include <clangsupport/clangcodemodelclientinterface.h> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -IAsyncJob::AsyncPrepareResult UpdateExtraAnnotationsJob::prepareAsyncRun() -{ - const JobRequest jobRequest = context().jobRequest; - QTC_ASSERT(acquireDocument(), return AsyncPrepareResult()); - - const TranslationUnit translationUnit = *m_translationUnit; - setRunner([translationUnit]() { - TIME_SCOPE_DURATION("UpdateExtraAnnotationsJobRunner"); - return translationUnit.fullTokenInfos().toTokenInfoContainers(); - }); - - return AsyncPrepareResult{translationUnit.id()}; -} - -void UpdateExtraAnnotationsJob::finalizeAsyncRun() -{ - if (context().isOutdated()) - return; - - context().client->annotations(AnnotationsMessage(m_pinnedFileContainer, asyncResult())); -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/clangupdateextraannotationsjob.h b/src/tools/clangbackend/source/clangupdateextraannotationsjob.h deleted file mode 100644 index 2a0e0db84e..0000000000 --- a/src/tools/clangbackend/source/clangupdateextraannotationsjob.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangdocumentjob.h" - -#include <clangsupport/tokeninfocontainer.h> - -namespace ClangBackEnd { - -using UpdateExtraAnnotationsJobResult = QVector<TokenInfoContainer>; - -class UpdateExtraAnnotationsJob : public DocumentJob<UpdateExtraAnnotationsJobResult> -{ -public: - AsyncPrepareResult prepareAsyncRun() override; - void finalizeAsyncRun() override; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/codecompleter.cpp b/src/tools/clangbackend/source/codecompleter.cpp deleted file mode 100644 index ae49b650dd..0000000000 --- a/src/tools/clangbackend/source/codecompleter.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "codecompleter.h" - -#include "clangbackend_global.h" -#include "clangcodecompleteresults.h" -#include "clangdocument.h" -#include "clangexceptions.h" -#include "clangfilepath.h" -#include "clangstring.h" -#include "clangtranslationunitupdater.h" -#include "clangunsavedfilesshallowarguments.h" -#include "codecompletionsextractor.h" -#include "cursor.h" -#include "sourcelocation.h" -#include "sourcerange.h" -#include "unsavedfile.h" -#include "unsavedfiles.h" - -#include <utils/qtcassert.h> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -namespace { - -CodeCompletions toCodeCompletions(const UnsavedFile &unsavedFile, - const ClangCodeCompleteResults &results, - bool onlyFunctionOverloads) -{ - if (results.isNull()) - return CodeCompletions(); - - CodeCompletionsExtractor extractor(unsavedFile, results.data()); - CodeCompletions codeCompletions = extractor.extractAll(onlyFunctionOverloads); - - return codeCompletions; -} - -// CLANG-UPGRADE-CHECK: Remove this workaround once we require LLVM/Clang 11 as that version makes -// the workaround pointless. -void filterUnknownContextResults(ClangCodeCompleteResults &results, - const UnsavedFile &theUnsavedFile, - uint line, - uint column) -{ - if (results.hasUnknownContext()) { - bool positionIsOk = false; - const uint position = theUnsavedFile.toUtf8Position(line, column - 1, &positionIsOk); - if (positionIsOk && (theUnsavedFile.hasCharacterAt(position, '.') - || (theUnsavedFile.hasCharacterAt(position - 1, '-') - && theUnsavedFile.hasCharacterAt(position, '>')))) { - results = {}; - } - } -} - -} // anonymous namespace - -CodeCompleter::CodeCompleter(const TranslationUnit &translationUnit, - const UnsavedFiles &unsavedFiles) - : translationUnit(translationUnit) - , unsavedFiles(unsavedFiles) -{ -} - -static void replaceWithOpeningParen(UnsavedFile &file, uint line, uint column) -{ - bool ok; - const uint pos = file.toUtf8Position(line, column, &ok); - QTC_ASSERT(ok, return;); - file.replaceAt(pos, 1, Utf8String("(", 1)); -} - -CodeCompletions CodeCompleter::complete(int line, int column, - int funcNameStartLine, - int funcNameStartColumn) -{ - if (funcNameStartLine >= 0) { - UnsavedFile &file = unsavedFiles.unsavedFile(translationUnit.filePath()); - // Replace '{' by '(' to get proper FunctionOverloadCompletionKind for constructor. - if (file.hasCharacterAt(line, column - 1, '{')) - replaceWithOpeningParen(file, line, column - 1); - } - - // Check if we have a smart pointer completion and get proper constructor signatures in results. - // Results are empty when it's not a smart pointer or this completion failed. - ClangCodeCompleteResults clangCompletions = completeSmartPointerCreation(line, - column, - funcNameStartLine, - funcNameStartColumn); - - // Default completion. - if (clangCompletions.isNull() || clangCompletions.isEmpty()) - clangCompletions = completeHelper(line, column); - - filterUnknownContextResults(clangCompletions, unsavedFile(), line, column); - - return toCodeCompletions(unsavedFiles.unsavedFile(translationUnit.filePath()), - clangCompletions, - funcNameStartLine >= 0); -} - -// For given "make_unique<T>" / "make_shared<T>" / "QSharedPointer<T>::create" return "new T(" -// Otherwize return empty QString -static QString tweakName(const Utf8String &oldName) -{ - if (!oldName.contains('>')) - return QString(); - - QString fullName = oldName.toString().trimmed(); - if (!fullName.endsWith('>')) { - // This is the class<type>::method case - remove ::method part - if (!fullName.endsWith("create") || !fullName.contains("QSharedPointer")) - return QString(); - fullName = fullName.mid(0, fullName.lastIndexOf(':') - 1); - } else if (!fullName.contains("make_unique") && !fullName.contains("make_shared")) { - return QString(); - } - int templateStart = fullName.indexOf('<'); - QString templatePart = fullName.mid(templateStart + 1, - fullName.length() - templateStart - 2); - return "new " + templatePart + "("; -} - -ClangCodeCompleteResults CodeCompleter::completeSmartPointerCreation(uint line, - uint column, - int funcNameStartLine, - int funcNameStartColumn) -{ - if (column <= 1 || funcNameStartLine == -1) - return ClangCodeCompleteResults(); - - UnsavedFile &file = unsavedFiles.unsavedFile(translationUnit.filePath()); - if (!file.hasCharacterAt(line, column - 1, '(')) - return ClangCodeCompleteResults(); - - bool ok; - const uint startPos = file.toUtf8Position(funcNameStartLine, funcNameStartColumn, &ok); - QTC_ASSERT(ok, return ClangCodeCompleteResults();); - const uint endPos = file.toUtf8Position(line, column - 1, &ok); - QTC_ASSERT(ok, return ClangCodeCompleteResults();); - - const Utf8String content = file.fileContent(); - const Utf8String oldName = content.mid(startPos, endPos - startPos); - const QString updatedName = tweakName(oldName); - if (updatedName.isEmpty()) - return ClangCodeCompleteResults(); - - column += updatedName.length(); - file.replaceAt(endPos + 1, 0, updatedName); - - ClangCodeCompleteResults results = completeHelper(line, column); - if (results.isEmpty()) { - column -= updatedName.length(); - file.replaceAt(endPos + 1, updatedName.length(), QString()); - } - return results; -} - -ClangCodeCompleteResults CodeCompleter::completeHelper(uint line, uint column) -{ - const Utf8String nativeFilePath = FilePath::toNativeSeparators(translationUnit.filePath()); - UnsavedFilesShallowArguments unsaved = unsavedFiles.shallowArguments(); - - return clang_codeCompleteAt(translationUnit.cxTranslationUnit(), - nativeFilePath.constData(), - line, - column, - unsaved.data(), - unsaved.count(), - defaultOptions()); -} - -uint CodeCompleter::defaultOptions() const -{ - uint options = CXCodeComplete_IncludeMacros - | CXCodeComplete_IncludeCompletionsWithFixIts - | CXCodeComplete_IncludeCodePatterns; - - if (TranslationUnitUpdater::defaultParseOptions() - & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion) { - options |= CXCodeComplete_IncludeBriefComments; - } - - return options; -} - -UnsavedFile &CodeCompleter::unsavedFile() -{ - return unsavedFiles.unsavedFile(translationUnit.filePath()); -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/codecompleter.h b/src/tools/clangbackend/source/codecompleter.h deleted file mode 100644 index 3fdab36b57..0000000000 --- a/src/tools/clangbackend/source/codecompleter.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangtranslationunit.h" -#include "unsavedfiles.h" - -#include <codecompletion.h> - -#include <utf8stringvector.h> - -namespace ClangBackEnd { - -class ClangCodeCompleteResults; - -class CodeCompleter -{ -public: - CodeCompleter(const TranslationUnit &translationUnit, - const UnsavedFiles &unsavedFiles); - - CodeCompletions complete(int line, int column, - int funcNameStartLine = -1, - int funcNameStartColumn = -1); - -private: - uint defaultOptions() const; - UnsavedFile &unsavedFile(); - - ClangCodeCompleteResults completeHelper(uint line, uint column); - ClangCodeCompleteResults completeSmartPointerCreation(uint line, - uint column, - int funcNameStartLine, - int funcNameStartColumn); - -private: - TranslationUnit translationUnit; - UnsavedFiles unsavedFiles; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/codecompletionchunkconverter.cpp b/src/tools/clangbackend/source/codecompletionchunkconverter.cpp deleted file mode 100644 index 76c578643f..0000000000 --- a/src/tools/clangbackend/source/codecompletionchunkconverter.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "codecompletionchunkconverter.h" - -#include "clangstring.h" - -namespace ClangBackEnd { - -void CodeCompletionChunkConverter::extractCompletionChunks(CXCompletionString completionString) -{ - const uint completionChunkCount = clang_getNumCompletionChunks(completionString); - chunks.reserve(completionChunkCount); - - for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) { - const CodeCompletionChunk::Kind kind = chunkKind(completionString, chunkIndex); - - if (kind == CodeCompletionChunk::Optional) { - extractOptionalCompletionChunks(clang_getCompletionChunkCompletionString(completionString, chunkIndex)); - } else { - chunks.append(CodeCompletionChunk(kind, - chunkText(completionString, chunkIndex))); - } - } -} - -void CodeCompletionChunkConverter::extractOptionalCompletionChunks(CXCompletionString completionString) -{ - const uint completionChunkCount = clang_getNumCompletionChunks(completionString); - - for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) { - const CodeCompletionChunk::Kind kind = chunkKind(completionString, chunkIndex); - - if (kind == CodeCompletionChunk::Optional) - extractOptionalCompletionChunks(clang_getCompletionChunkCompletionString(completionString, chunkIndex)); - else - chunks.append(CodeCompletionChunk(kind, chunkText(completionString, chunkIndex), true)); - } -} - -CodeCompletionChunk::Kind CodeCompletionChunkConverter::chunkKind(CXCompletionString completionString, uint chunkIndex) -{ - return CodeCompletionChunk::Kind(clang_getCompletionChunkKind(completionString, chunkIndex)); -} - -CodeCompletionChunks CodeCompletionChunkConverter::extract(CXCompletionString completionString) -{ - CodeCompletionChunkConverter converter; - - converter.extractCompletionChunks(completionString); - - return converter.chunks; -} - -Utf8String CodeCompletionChunkConverter::chunkText(CXCompletionString completionString, uint chunkIndex) -{ - return ClangString(clang_getCompletionChunkText(completionString, chunkIndex)); -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/codecompletionchunkconverter.h b/src/tools/clangbackend/source/codecompletionchunkconverter.h deleted file mode 100644 index 0bfb1a19c1..0000000000 --- a/src/tools/clangbackend/source/codecompletionchunkconverter.h +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <codecompletionchunk.h> - -#include <QVector> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -class CodeCompletionChunkConverter -{ -public: - static CodeCompletionChunks extract(CXCompletionString completionString); - - static Utf8String chunkText(CXCompletionString completionString, uint chunkIndex); - -private: - static CodeCompletionChunk::Kind chunkKind(CXCompletionString completionString, uint chunkIndex); - void extractCompletionChunks(CXCompletionString completionString); - void extractOptionalCompletionChunks(CXCompletionString completionString); - -private: - CodeCompletionChunks chunks; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/codecompletionsextractor.cpp b/src/tools/clangbackend/source/codecompletionsextractor.cpp deleted file mode 100644 index c2386149be..0000000000 --- a/src/tools/clangbackend/source/codecompletionsextractor.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "codecompletionsextractor.h" - -#include "clangbackend_global.h" -#include "clangstring.h" -#include "clangtranslationunit.h" -#include "codecompletionchunkconverter.h" -#include "sourcelocation.h" -#include "sourcerange.h" -#include "unsavedfile.h" - -#include <utils/algorithm.h> -#include <utils/qtcassert.h> - -#include <QPair> -#include <QDebug> - -#include <cmath> -#include <limits> - -namespace ClangBackEnd { - -CodeCompletionsExtractor::CodeCompletionsExtractor(const UnsavedFile &unsavedFile, - CXCodeCompleteResults *cxCodeCompleteResults) - : unsavedFile(unsavedFile) - , cxCodeCompleteResults(cxCodeCompleteResults) -{ -} - -bool CodeCompletionsExtractor::next() -{ - const uint cxCodeCompleteResultCount = cxCodeCompleteResults->NumResults; - - if (cxCodeCompleteResultIndex < cxCodeCompleteResultCount) { - currentCxCodeCompleteResult = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex]; - - currentCodeCompletion_ = CodeCompletion(); - - extractCompletionKind(); - extractText(); - extractPriority(); - extractAvailability(); - extractHasParameters(); - extractBriefComment(); - extractCompletionChunks(); - adaptPriority(); - extractRequiredFixIts(); - - ++cxCodeCompleteResultIndex; - - return true; - } - - return false; -} - -bool CodeCompletionsExtractor::peek(const Utf8String &name) -{ - const uint cxCodeCompleteResultCount = cxCodeCompleteResults->NumResults; - - uint peekCxCodeCompleteResultIndex = cxCodeCompleteResultIndex; - - while (peekCxCodeCompleteResultIndex < cxCodeCompleteResultCount) { - if (hasText(name, cxCodeCompleteResults->Results[peekCxCodeCompleteResultIndex].CompletionString)) - return true; - - ++peekCxCodeCompleteResultIndex; - } - - return false; -} - -CodeCompletions CodeCompletionsExtractor::extractAll(bool onlyFunctionOverloads) -{ - CodeCompletions codeCompletions; - codeCompletions.reserve(int(cxCodeCompleteResults->NumResults)); - - while (next()) - codeCompletions.append(currentCodeCompletion_); - - handleCompletions(codeCompletions, onlyFunctionOverloads); - - return codeCompletions; -} - -static CodeCompletions filterFunctionOverloads(const CodeCompletions &completions) -{ - return ::Utils::filtered(completions, [](const CodeCompletion &completion) { - return completion.completionKind == CodeCompletion::FunctionOverloadCompletionKind; - }); -} - -static void adaptOverloadsPriorities(CodeCompletions &codeCompletions) -{ - std::map<Utf8String, std::vector<CodeCompletion *>> cachedOverloads; - for (CodeCompletion ¤tCompletion : codeCompletions) { - if (currentCompletion.completionKind != CodeCompletion::ConstructorCompletionKind - && currentCompletion.completionKind != CodeCompletion::FunctionCompletionKind - && currentCompletion.completionKind - != CodeCompletion::FunctionDefinitionCompletionKind) { - continue; - } - - auto found = cachedOverloads.find(currentCompletion.text); - if (found == cachedOverloads.end()) { - cachedOverloads[currentCompletion.text].push_back(¤tCompletion); - } else { - const quint32 oldPriority = found->second.front()->priority; - if (currentCompletion.priority >= oldPriority) { - currentCompletion.priority = oldPriority; - } else { - const quint32 newPriority = currentCompletion.priority; - for (CodeCompletion *completion : found->second) - completion->priority = newPriority; - } - found->second.push_back(¤tCompletion); - } - } -} - -static int comparePriorities(quint32 p1, quint32 p2) -{ - static const int fuzziness = 2; // Each of const and volatile can introduce a diff of 1. - const int diff = p1 - p2; - if (std::abs(diff) > fuzziness) - return diff; - return 0; -} - -// The list is already ordered, but since we pass the priorities up to higher layers, -// we should make sure that adjacent values become identical. -static void mergeAdjacentPriorities(CodeCompletions &completions) -{ - static const int maxValue = std::numeric_limits<quint32>::max(); - QPair<QVector<CodeCompletion *>, quint32> priorityGroup; - priorityGroup.second = maxValue; - const auto assignGroupPriority = [&priorityGroup] { - for (CodeCompletion * const c : qAsConst(priorityGroup.first)) - c->priority = priorityGroup.second; - }; - for (CodeCompletion ¤tCompletion : completions) { - const int prioCmp = comparePriorities(priorityGroup.second, currentCompletion.priority); - if (prioCmp < 0) { - assignGroupPriority(); - priorityGroup.first.clear(); - priorityGroup.second = currentCompletion.priority; - } else if (currentCompletion.priority > priorityGroup.second) - priorityGroup.second = currentCompletion.priority; - priorityGroup.first << ¤tCompletion; - } - assignGroupPriority(); -} - -static void sortCodeCompletions(CodeCompletions &codeCompletions) -{ - auto currentItemsCompare = [](const CodeCompletion &first, - const CodeCompletion &second) { - // Items without fix-its come first. - if (first.requiredFixIts.empty() != second.requiredFixIts.empty()) - return first.requiredFixIts.empty() > second.requiredFixIts.empty(); - - const int prioCmpResult = comparePriorities(first.priority, second.priority); - if (prioCmpResult != 0) - return prioCmpResult < 0; - - const int textCmp = first.text.toString().compare(second.text); - if (textCmp != 0) - return textCmp < 0; - - return first.completionKind < second.completionKind; - }; - - // Keep the order for the items with the same priority and name. - std::stable_sort(codeCompletions.begin(), codeCompletions.end(), currentItemsCompare); -} - -void CodeCompletionsExtractor::handleCompletions(CodeCompletions &codeCompletions, - bool onlyFunctionOverloads) -{ - if (onlyFunctionOverloads) { - const CodeCompletions overloadCompletions = filterFunctionOverloads(codeCompletions); - - // If filtered completions are empty the assumption we need function overloads is wrong - // therefore we do not use filtered results in that case. - if (!overloadCompletions.isEmpty()) - codeCompletions = overloadCompletions; - } - - adaptOverloadsPriorities(codeCompletions); - sortCodeCompletions(codeCompletions); - mergeAdjacentPriorities(codeCompletions); -} - -void CodeCompletionsExtractor::extractCompletionKind() -{ - switch (currentCxCodeCompleteResult.CursorKind) { - case CXCursor_FunctionTemplate: - currentCodeCompletion_.completionKind = CodeCompletion::TemplateFunctionCompletionKind; - break; - case CXCursor_CXXMethod: - extractMethodCompletionKind(); - break; - case CXCursor_FunctionDecl: - case CXCursor_ConversionFunction: - currentCodeCompletion_.completionKind = CodeCompletion::FunctionCompletionKind; - break; - case CXCursor_VariableRef: - case CXCursor_MemberRef: - case CXCursor_VarDecl: - case CXCursor_FieldDecl: - case CXCursor_ParmDecl: - case CXCursor_NonTypeTemplateParameter: - currentCodeCompletion_.completionKind = CodeCompletion::VariableCompletionKind; - break; - case CXCursor_StructDecl: - case CXCursor_UnionDecl: - case CXCursor_ClassDecl: - case CXCursor_TemplateTypeParameter: - currentCodeCompletion_.completionKind = CodeCompletion::ClassCompletionKind; - break; - case CXCursor_TypedefDecl: - case CXCursor_TypeAliasDecl: - currentCodeCompletion_.completionKind = CodeCompletion::TypeAliasCompletionKind; - break; - case CXCursor_ClassTemplatePartialSpecialization: - case CXCursor_ClassTemplate: - case CXCursor_TemplateTemplateParameter: - currentCodeCompletion_.completionKind = CodeCompletion::TemplateClassCompletionKind; - break; - case CXCursor_Namespace: - case CXCursor_NamespaceAlias: - currentCodeCompletion_.completionKind = CodeCompletion::NamespaceCompletionKind; - break; - case CXCursor_EnumDecl: - currentCodeCompletion_.completionKind = CodeCompletion::EnumerationCompletionKind; - break; - case CXCursor_EnumConstantDecl: - currentCodeCompletion_.completionKind = CodeCompletion::EnumeratorCompletionKind; - break; - case CXCursor_Constructor: - currentCodeCompletion_.completionKind = CodeCompletion::ConstructorCompletionKind; - break; - case CXCursor_Destructor: - currentCodeCompletion_.completionKind = CodeCompletion::DestructorCompletionKind; - break; - case CXCursor_MacroDefinition: - extractMacroCompletionKind(); - break; - case CXCursor_NotImplemented: - currentCodeCompletion_.completionKind = CodeCompletion::KeywordCompletionKind; - break; - case CXCursor_OverloadCandidate: - currentCodeCompletion_.completionKind = CodeCompletion::FunctionOverloadCompletionKind; - break; - default: - currentCodeCompletion_.completionKind = CodeCompletion::Other; - } -} - -void CodeCompletionsExtractor::extractText() -{ - const uint completionChunkCount = clang_getNumCompletionChunks(currentCxCodeCompleteResult.CompletionString); - for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) { - const CXCompletionChunkKind chunkKind = clang_getCompletionChunkKind(currentCxCodeCompleteResult.CompletionString, chunkIndex); - if (chunkKind == CXCompletionChunk_TypedText) { - currentCodeCompletion_.text = CodeCompletionChunkConverter::chunkText(currentCxCodeCompleteResult.CompletionString, chunkIndex); - break; - } - } -} - -void CodeCompletionsExtractor::extractMethodCompletionKind() -{ - CXCompletionString cxCompletionString = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex].CompletionString; - - const unsigned long long contexts = clang_codeCompleteGetContexts(cxCodeCompleteResults); - - const uint annotationCount = clang_getCompletionNumAnnotations(cxCompletionString); - - for (uint annotationIndex = 0; annotationIndex < annotationCount; ++annotationIndex) { - ClangString annotation = clang_getCompletionAnnotation(cxCompletionString, annotationIndex); - - if (annotation == Utf8StringLiteral("qt_signal")) { - currentCodeCompletion_.completionKind = CodeCompletion::SignalCompletionKind; - return; - } - - if (annotation == Utf8StringLiteral("qt_slot")) { - currentCodeCompletion_.completionKind = CodeCompletion::SlotCompletionKind; - return; - } - } - - currentCodeCompletion_.completionKind = CodeCompletion::FunctionDefinitionCompletionKind; - if ((contexts & CXCompletionContext_DotMemberAccess) - || (contexts & CXCompletionContext_ArrowMemberAccess)) { - currentCodeCompletion_.completionKind = CodeCompletion::FunctionCompletionKind; - } -} - -void CodeCompletionsExtractor::extractMacroCompletionKind() -{ - CXCompletionString cxCompletionString = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex].CompletionString; - - const uint completionChunkCount = clang_getNumCompletionChunks(cxCompletionString); - - for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) { - CXCompletionChunkKind kind = clang_getCompletionChunkKind(cxCompletionString, chunkIndex); - if (kind == CXCompletionChunk_Placeholder) { - currentCodeCompletion_.completionKind = CodeCompletion::FunctionCompletionKind; - return; - } - } - - currentCodeCompletion_.completionKind = CodeCompletion::PreProcessorCompletionKind; -} - -void CodeCompletionsExtractor::extractPriority() -{ - CXCompletionString cxCompletionString = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex].CompletionString; - quint32 priority = clang_getCompletionPriority(cxCompletionString); - currentCodeCompletion_.priority = priority; -} - -void CodeCompletionsExtractor::extractAvailability() -{ - CXCompletionString cxCompletionString = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex].CompletionString; - CXAvailabilityKind cxAvailabilityKind = clang_getCompletionAvailability(cxCompletionString); - - switch (cxAvailabilityKind) { - case CXAvailability_Available: - currentCodeCompletion_.availability = CodeCompletion::Available; - break; - case CXAvailability_Deprecated: - currentCodeCompletion_.availability = CodeCompletion::Deprecated; - break; - case CXAvailability_NotAvailable: - currentCodeCompletion_.availability = CodeCompletion::NotAvailable; - break; - case CXAvailability_NotAccessible: - // QTCREATORBUG-25244 - if (currentCodeCompletion_.completionKind == CodeCompletion::FunctionDefinitionCompletionKind) - currentCodeCompletion_.availability = CodeCompletion::Available; - else - currentCodeCompletion_.availability = CodeCompletion::NotAccessible; - break; - } -} - -void CodeCompletionsExtractor::extractHasParameters() -{ - const uint completionChunkCount = clang_getNumCompletionChunks(currentCxCodeCompleteResult.CompletionString); - for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) { - const CXCompletionChunkKind chunkKind = clang_getCompletionChunkKind(currentCxCodeCompleteResult.CompletionString, chunkIndex); - if (chunkKind == CXCompletionChunk_LeftParen) { - const CXCompletionChunkKind nextChunkKind = clang_getCompletionChunkKind(currentCxCodeCompleteResult.CompletionString, chunkIndex + 1); - currentCodeCompletion_.hasParameters = nextChunkKind != CXCompletionChunk_RightParen; - return; - } - } -} - -void CodeCompletionsExtractor::extractBriefComment() -{ - ClangString briefComment = clang_getCompletionBriefComment(currentCxCodeCompleteResult.CompletionString); - - currentCodeCompletion_.briefComment = briefComment; -} - -void CodeCompletionsExtractor::extractCompletionChunks() -{ - currentCodeCompletion_.chunks = CodeCompletionChunkConverter::extract(currentCxCodeCompleteResult.CompletionString); -} - -SourceRangeContainer toRangeContainer(const UnsavedFile &file, CXSourceRange cxSourceRange) -{ - const CXSourceLocation start = clang_getRangeStart(cxSourceRange); - const CXSourceLocation end = clang_getRangeEnd(cxSourceRange); - - uint startLine = 0; - uint startColumn = 0; - uint endLine = 0; - uint endColumn = 0; - clang_getFileLocation(start, nullptr, &startLine, &startColumn, nullptr); - clang_getFileLocation(end, nullptr, &endLine, &endColumn, nullptr); - QTC_ASSERT(startLine == endLine, return SourceRangeContainer();); - - const Utf8String lineText = file.lineRange(startLine, endLine); - startColumn = lineText.mid(0, startColumn - 1).toString().size() + 1; - endColumn = lineText.mid(0, endColumn - 1).toString().size() + 1; - - return SourceRangeContainer(SourceLocationContainer(file.filePath(), startLine, startColumn), - SourceLocationContainer(file.filePath(), endLine, endColumn)); -} - -void CodeCompletionsExtractor::extractRequiredFixIts() -{ - unsigned fixItsNumber = clang_getCompletionNumFixIts(cxCodeCompleteResults, - cxCodeCompleteResultIndex); - - if (!fixItsNumber) - return; - - CXSourceRange range; - for (unsigned i = 0; i < fixItsNumber; ++i) { - ClangString fixIt = clang_getCompletionFixIt(cxCodeCompleteResults, - cxCodeCompleteResultIndex, - i, - &range); - currentCodeCompletion_.requiredFixIts.push_back( - FixItContainer(Utf8String(fixIt), toRangeContainer(unsavedFile, range))); - } -} - -void CodeCompletionsExtractor::adaptPriority() -{ - decreasePriorityForDestructors(); - decreasePriorityForNonAvailableCompletions(); - decreasePriorityForQObjectInternals(); - decreasePriorityForSignals(); - decreasePriorityForOperators(); -} - -void CodeCompletionsExtractor::decreasePriorityForNonAvailableCompletions() -{ - if (currentCodeCompletion_.availability != CodeCompletion::Available) - currentCodeCompletion_.priority = currentCodeCompletion_.priority * 100; -} - -void CodeCompletionsExtractor::decreasePriorityForDestructors() -{ - if (currentCodeCompletion_.completionKind == CodeCompletion::DestructorCompletionKind) - currentCodeCompletion_.priority = currentCodeCompletion_.priority * 100; -} - -void CodeCompletionsExtractor::decreasePriorityForSignals() -{ - if (currentCodeCompletion_.completionKind == CodeCompletion::SignalCompletionKind) - currentCodeCompletion_.priority = currentCodeCompletion_.priority * 100; -} - -void CodeCompletionsExtractor::decreasePriorityForQObjectInternals() -{ - quint32 priority = currentCodeCompletion_.priority; - - if (currentCodeCompletion_.text.startsWith("qt_")) - priority *= 100; - - if (currentCodeCompletion_.text == Utf8StringLiteral("metaObject")) - priority *= 10; - - if (currentCodeCompletion_.text == Utf8StringLiteral("staticMetaObject")) - priority *= 100; - - currentCodeCompletion_.priority = priority; -} - -bool isOperator(CXCursorKind cxCursorKind, const Utf8String &name) -{ - return cxCursorKind == CXCursor_ConversionFunction - || (cxCursorKind == CXCursor_CXXMethod - && name.startsWith(Utf8StringLiteral("operator"))); -} - -void CodeCompletionsExtractor::decreasePriorityForOperators() -{ - quint32 priority = currentCodeCompletion_.priority; - - if (isOperator(currentCxCodeCompleteResult.CursorKind, currentCodeCompletion().text)) - priority *= 100; - - currentCodeCompletion_.priority = priority; -} - -bool CodeCompletionsExtractor::hasText(const Utf8String &text, CXCompletionString cxCompletionString) const -{ - const uint completionChunkCount = clang_getNumCompletionChunks(cxCompletionString); - - for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) { - const CXCompletionChunkKind chunkKind = clang_getCompletionChunkKind(cxCompletionString, chunkIndex); - if (chunkKind == CXCompletionChunk_TypedText) { - const ClangString currentText(clang_getCompletionChunkText(cxCompletionString, chunkIndex)); - return text == currentText; - } - } - - return false; -} - -const CodeCompletion &CodeCompletionsExtractor::currentCodeCompletion() const -{ - return currentCodeCompletion_; -} - -std::ostream &operator<<(std::ostream &os, const CodeCompletionsExtractor &extractor) -{ - os << "name: " << extractor.currentCodeCompletion().text - << ", kind: " << extractor.currentCodeCompletion().completionKind - << ", priority: " << extractor.currentCodeCompletion().priority - << ", kind: " << extractor.currentCodeCompletion().availability; - - return os; -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/codecompletionsextractor.h b/src/tools/clangbackend/source/codecompletionsextractor.h deleted file mode 100644 index 408badc748..0000000000 --- a/src/tools/clangbackend/source/codecompletionsextractor.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <codecompletion.h> - -#include <clang-c/Index.h> - -#include <QVector> - -#include <iosfwd> - -namespace ClangBackEnd { - -class UnsavedFile; - -class CodeCompletionsExtractor -{ -public: - CodeCompletionsExtractor(const UnsavedFile &unsavedFile, - CXCodeCompleteResults *cxCodeCompleteResults); - - CodeCompletionsExtractor(CodeCompletionsExtractor&) = delete; - CodeCompletionsExtractor &operator=(CodeCompletionsExtractor&) = delete; - - CodeCompletionsExtractor(CodeCompletionsExtractor&&) = delete; - CodeCompletionsExtractor &operator=(CodeCompletionsExtractor&&) = delete; - - bool next(); - bool peek(const Utf8String &name); - - CodeCompletions extractAll(bool onlyFunctionOverloads); - - const CodeCompletion ¤tCodeCompletion() const; - -private: - void extractCompletionKind(); - void extractText(); - void extractMethodCompletionKind(); - void extractMacroCompletionKind(); - void extractPriority(); - void extractAvailability(); - void extractHasParameters(); - void extractBriefComment(); - void extractCompletionChunks(); - void extractRequiredFixIts(); - - void adaptPriority(); - void decreasePriorityForNonAvailableCompletions(); - void decreasePriorityForDestructors(); - void decreasePriorityForSignals(); - void decreasePriorityForQObjectInternals(); - void decreasePriorityForOperators(); - - void handleCompletions(CodeCompletions &codeCompletions, bool onlyFunctionOverloads); - - bool hasText(const Utf8String &text, CXCompletionString cxCompletionString) const; - -private: - CodeCompletion currentCodeCompletion_; - const UnsavedFile &unsavedFile; - CXCompletionResult currentCxCodeCompleteResult{CXCursor_UnexposedDecl, nullptr}; - CXCodeCompleteResults *cxCodeCompleteResults = nullptr; - uint cxCodeCompleteResultIndex = 0; -}; - -std::ostream &operator<<(std::ostream &os, const CodeCompletionsExtractor &extractor); -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/commandlinearguments.cpp b/src/tools/clangbackend/source/commandlinearguments.cpp deleted file mode 100644 index cde7329525..0000000000 --- a/src/tools/clangbackend/source/commandlinearguments.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "commandlinearguments.h" - -#include "clangfilepath.h" - -#include <utf8string.h> -#include <utils/algorithm.h> -#include <utils/qtcprocess.h> - -#include <QByteArray> -#include <QDebug> - -static QList<QByteArray> splitArgs(QString &argsString) -{ - QList<QByteArray> result; - Utils::ProcessArgs::ArgIterator it(&argsString); - while (it.next()) - result.append(it.value().toUtf8()); - return result; -} - -template<size_t Size> -static QList<QByteArray> extraOptions(const char(&environment)[Size]) -{ - if (!qEnvironmentVariableIsSet(environment)) - return QList<QByteArray>(); - QString arguments = QString::fromLocal8Bit(qgetenv(environment)); - return splitArgs(arguments); -} - -static QList<QByteArray> extraClangCodeModelPrependOptions() { - constexpr char ccmPrependOptions[] = "QTC_CLANG_CCM_CMD_PREPEND"; - static const QList<QByteArray> options = extraOptions(ccmPrependOptions); - if (!options.isEmpty()) - qWarning() << "ClangCodeModel options are prepended with " << options; - return options; -} - -static QList<QByteArray> extraClangCodeModelAppendOptions() { - constexpr char ccmAppendOptions[] = "QTC_CLANG_CCM_CMD_APPEND"; - static const QList<QByteArray> options = extraOptions(ccmAppendOptions); - if (!options.isEmpty()) - qWarning() << "ClangCodeModel options are appended with " << options; - return options; -} - -namespace ClangBackEnd { - -CommandLineArguments::CommandLineArguments(const char *filePath, - const Utf8StringVector &compilationArguments, - bool addVerboseOption) - : m_prependArgs(extraClangCodeModelPrependOptions()), - m_appendArgs(extraClangCodeModelAppendOptions()) -{ - const int elementsToReserve = m_prependArgs.size() - + compilationArguments.size() - + (addVerboseOption ? 1 : 0) - + m_appendArgs.size(); - m_arguments.reserve(static_cast<size_t>(elementsToReserve)); - - for (const auto &argument : m_prependArgs) - m_arguments.push_back(argument.constData()); - for (const auto &argument : compilationArguments) - m_arguments.push_back(argument.constData()); - if (addVerboseOption) - m_arguments.push_back("-v"); - for (const auto &argument : m_appendArgs) - m_arguments.push_back(argument.constData()); - m_nativeFilePath = FilePath::toNativeSeparators(Utf8String::fromUtf8(filePath)); - m_arguments.push_back(m_nativeFilePath.constData()); -} - -const char * const *CommandLineArguments::data() const -{ - return m_arguments.data(); -} - -int CommandLineArguments::count() const -{ - return int(m_arguments.size()); -} - -const char *CommandLineArguments::at(int position) const -{ - return m_arguments.at(uint(position)); -} - -static Utf8String maybeQuoted(const char *argumentAsCString) -{ - const QString argumentAsQString = QString::fromUtf8(argumentAsCString); - const QString quotedArgument = Utils::ProcessArgs::quoteArg(argumentAsQString); - - return Utf8String::fromString(quotedArgument); -} - -void CommandLineArguments::print() const -{ - auto cerr = qCritical(); - cerr << "Arguments to libclang:"; - for (const auto &argument : m_arguments) - cerr.noquote() << maybeQuoted(argument).constData(); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/commandlinearguments.h b/src/tools/clangbackend/source/commandlinearguments.h deleted file mode 100644 index 9251ae124b..0000000000 --- a/src/tools/clangbackend/source/commandlinearguments.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <utf8stringvector.h> - -#include <vector> - -namespace ClangBackEnd { - -class CommandLineArguments -{ -public: - CommandLineArguments(const char *filePath, - const Utf8StringVector &compilationArguments, - bool addVerboseOption); - - const char * const *data() const; - int count() const; - const char * at(int position) const; - - void print() const; - -private: - Utf8String m_nativeFilePath; - const QList<QByteArray> m_prependArgs; - const QList<QByteArray> m_appendArgs; - std::vector<const char *> m_arguments; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/cursor.cpp b/src/tools/clangbackend/source/cursor.cpp deleted file mode 100644 index be84a64331..0000000000 --- a/src/tools/clangbackend/source/cursor.cpp +++ /dev/null @@ -1,544 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "cursor.h" - -#include "clangstring.h" -#include "sourcelocation.h" -#include "sourcerange.h" - -#include "clangbackend_global.h" - -#include <ostream> - -namespace ClangBackEnd { - -Cursor::Cursor() - : m_cxCursor(clang_getNullCursor()) -{ -} - -Cursor::Cursor(CXCursor cxCursor) - : m_cxCursor(cxCursor) -{ -} - -bool Cursor::isNull() const -{ - return clang_Cursor_isNull(m_cxCursor); -} - -bool Cursor::isValid() const -{ - return !clang_isInvalid(kind()); -} - -bool Cursor::isTranslationUnit() const -{ - return clang_isTranslationUnit(kind()); -} - -bool Cursor::isDefinition() const -{ - return clang_isCursorDefinition(m_cxCursor); -} - -bool Cursor::isDynamicCall() const -{ - return clang_Cursor_isDynamicCall(m_cxCursor); -} - -bool Cursor::isVirtualMethod() const -{ - return clang_CXXMethod_isVirtual(m_cxCursor); -} - -bool Cursor::isPureVirtualMethod() const -{ - return clang_CXXMethod_isPureVirtual(m_cxCursor); -} - -bool Cursor::isConstantMethod() const -{ - return clang_CXXMethod_isConst(m_cxCursor); -} - -bool Cursor::isStaticMethod() const -{ - return clang_CXXMethod_isStatic(m_cxCursor); -} - -bool Cursor::isCompoundType() const -{ - switch (kind()) { - case CXCursor_ClassDecl: - case CXCursor_StructDecl: - case CXCursor_UnionDecl: return true; - default: return false; - } -} - -bool Cursor::isDeclaration() const -{ - return clang_isDeclaration(kind()); -} - -bool Cursor::isInvalidDeclaration() const -{ - return clang_isInvalidDeclaration(m_cxCursor); -} - -bool Cursor::isParameter() const -{ - return kind() == CXCursor_ParmDecl; -} - -bool Cursor::isLocalVariable() const -{ - switch (semanticParent().kind()) { - case CXCursor_FunctionDecl: - case CXCursor_CXXMethod: - case CXCursor_Constructor: - case CXCursor_Destructor: - case CXCursor_ConversionFunction: - case CXCursor_FunctionTemplate: - case CXCursor_ObjCInstanceMethodDecl: return true; - default: - return false; - } -} - -bool Cursor::isReference() const -{ - return clang_isReference(kind()); -} - -bool Cursor::isExpression() const -{ - return clang_isExpression(kind()); -} - -bool Cursor::isFunctionLike() const -{ - const CXCursorKind k = kind(); - return k == CXCursor_FunctionDecl - || k == CXCursor_CXXMethod - || k == CXCursor_FunctionTemplate; -} - -bool Cursor::isConstructorOrDestructor() const -{ - const CXCursorKind k = kind(); - return k == CXCursor_Constructor - || k == CXCursor_Destructor; -} - -bool Cursor::isTemplateLike() const -{ - switch (kind()) { - case CXCursor_ClassTemplate: - case CXCursor_ClassTemplatePartialSpecialization: - return true; - case CXCursor_ClassDecl: - return specializedCursorTemplate().isValid(); - default: - return false; - } - - Q_UNREACHABLE(); -} - -bool Cursor::isAnyTypeAlias() const -{ - const CXCursorKind k = kind(); - return k == CXCursor_TypeAliasDecl - || k == CXCursor_TypedefDecl - || k == CXCursor_TypeAliasTemplateDecl; -} - -bool Cursor::hasFinalFunctionAttribute() const -{ - bool hasFinal = false; - - visit([&] (Cursor cursor, Cursor /*parent*/) { - if (cursor.kind() == CXCursor_CXXFinalAttr) { - hasFinal = true; - return CXChildVisit_Break; - } else { - return CXChildVisit_Recurse; - } - }); - - return hasFinal; -} - -bool Cursor::hasFinalClassAttribute() const -{ - bool hasFinal = false; - - visit([&] (Cursor cursor, Cursor /*parent*/) { - switch (cursor.kind()) { - case CXCursor_CXXFinalAttr: - hasFinal = true; - return CXChildVisit_Break; - case CXCursor_CXXMethod: - return CXChildVisit_Break; - default: - return CXChildVisit_Recurse; - } - }); - - return hasFinal; -} - -bool Cursor::isUnexposed() const -{ - return clang_isUnexposed(kind()); -} - -bool Cursor::isAnonymous() const -{ - return clang_Cursor_isAnonymous(m_cxCursor); -} - -ClangString Cursor::unifiedSymbolResolution() const -{ - return ClangString(clang_getCursorUSR(m_cxCursor)); -} - -ClangString Cursor::mangling() const -{ - return ClangString(clang_Cursor_getMangling(m_cxCursor)); -} - -ClangString Cursor::spelling() const -{ - return ClangString(clang_getCursorSpelling(m_cxCursor)); -} - -Utf8String Cursor::displayName() const -{ - Utf8String result = ClangString(clang_getCursorDisplayName(m_cxCursor)); - if (!result.hasContent() && isAnonymous()) - result = Utf8String("(anonymous)"); - return result; -} - -ClangString Cursor::briefComment() const -{ - return ClangString(clang_Cursor_getBriefCommentText(m_cxCursor)); -} - -Utf8String Cursor::rawComment() const -{ - Utf8String comment = ClangString(clang_Cursor_getRawCommentText(m_cxCursor)); - comment.replace(Utf8String("\r\n"), Utf8String("\n")); - return comment; -} - -int Cursor::argumentCount() const -{ - return clang_Cursor_getNumArguments(m_cxCursor); -} - -Type Cursor::type() const -{ - return clang_getCursorType(m_cxCursor); -} - -Type Cursor::nonPointerTupe() const -{ - auto typeResult = type(); - - if (typeResult.isPointer()) - typeResult = typeResult.pointeeType(); - - return typeResult; -} - -Type Cursor::enumType() const -{ - return clang_getEnumDeclIntegerType(m_cxCursor); -} - -long long Cursor::enumConstantValue() const -{ - return clang_getEnumConstantDeclValue(m_cxCursor); -} - -unsigned long long Cursor::enumConstantUnsignedValue() const -{ - return clang_getEnumConstantDeclUnsignedValue(m_cxCursor); -} - -Cursor Cursor::specializedCursorTemplate() const -{ - return clang_getSpecializedCursorTemplate(m_cxCursor); -} - -CXFile Cursor::includedFile() const -{ - return clang_getIncludedFile(m_cxCursor); -} - -SourceLocation Cursor::sourceLocation() const -{ - return {cxTranslationUnit(), clang_getCursorLocation(m_cxCursor)}; -} - -CXSourceLocation Cursor::cxSourceLocation() const -{ - return clang_getCursorLocation(m_cxCursor); -} - -SourceRange Cursor::sourceRange() const -{ - return {cxTranslationUnit(), clang_getCursorExtent(m_cxCursor)}; -} - -CXSourceRange Cursor::cxSourceRange() const -{ - return clang_getCursorExtent(m_cxCursor); -} - -CXTranslationUnit Cursor::cxTranslationUnit() const -{ - return clang_Cursor_getTranslationUnit(m_cxCursor); -} - -SourceRange Cursor::commentRange() const -{ - return {cxTranslationUnit(), clang_Cursor_getCommentRange(m_cxCursor)}; -} - -bool Cursor::hasSameSourceLocationAs(const Cursor &other) const -{ - return clang_equalLocations(clang_getCursorLocation(m_cxCursor), - clang_getCursorLocation(other.m_cxCursor)); -} - -Cursor Cursor::definition() const -{ - return clang_getCursorDefinition(m_cxCursor); -} - -Cursor Cursor::canonical() const -{ - return clang_getCanonicalCursor(m_cxCursor); -} - -Cursor Cursor::referenced() const -{ - return clang_getCursorReferenced(m_cxCursor); -} - -Cursor Cursor::semanticParent() const -{ - return clang_getCursorSemanticParent(m_cxCursor); -} - -Cursor Cursor::lexicalParent() const -{ - return clang_getCursorLexicalParent(m_cxCursor); -} - -Cursor Cursor::functionBaseDeclaration() const -{ - auto functionBaseCursor = functionBase(); - - if (functionBaseCursor.isValid()) - return functionBaseCursor.nonPointerTupe().canonical().declaration(); - else - return semanticParent().semanticParent(); -} - -Cursor Cursor::functionBase() const -{ - Cursor functionBaseCursor; - - visit([&] (Cursor cursor, Cursor /*parentCursor*/) { - switch (cursor.kind()) { - case CXCursor_DeclRefExpr: - functionBaseCursor = cursor; ; - return CXChildVisit_Break; - default: - return CXChildVisit_Recurse; - } - }); - - return functionBaseCursor; -} - -Type Cursor::resultType() const -{ - return clang_getResultType(type().m_cxType); -} - -Cursor Cursor::argument(int index) const -{ - return clang_Cursor_getArgument(m_cxCursor, index); -} - -unsigned Cursor::overloadedDeclarationsCount() const -{ - return clang_getNumOverloadedDecls(m_cxCursor); -} - -Cursor Cursor::overloadedDeclaration(unsigned index) const -{ - return clang_getOverloadedDecl(m_cxCursor, index); -} - -namespace { - -bool isNotUnexposedLValueReference(const Cursor &argument, const Type &argumentType) -{ - return !(argument.isUnexposed() && argumentType.isLValueReference()); -} - -} - -void Cursor::collectOutputArgumentRangesTo(std::vector<CXSourceRange> &outputArgumentRanges) const -{ - const Type callExpressionType = referenced().type(); - const int argumentCount = this->argumentCount(); - const std::size_t maxSize = std::size_t(std::max(0, argumentCount)) - + outputArgumentRanges.size(); - outputArgumentRanges.reserve(maxSize); - - for (int argumentIndex = 0; argumentIndex < argumentCount; ++argumentIndex) { - const Cursor argument = this->argument(argumentIndex); - const Type argumentType = callExpressionType.argument(argumentIndex); - - if (isNotUnexposedLValueReference(argument, argumentType) - && argumentType.isOutputArgument()) { - outputArgumentRanges.push_back(argument.cxSourceRange()); - } - } -} - -std::vector<CXSourceRange> Cursor::outputArgumentRanges() const -{ - std::vector<CXSourceRange> outputArgumentRanges; - - collectOutputArgumentRangesTo(outputArgumentRanges); - - return outputArgumentRanges; -} - -CXCursorKind Cursor::kind() const -{ - return clang_getCursorKind(m_cxCursor); -} - -CXCursor Cursor::cx() const -{ - return m_cxCursor; -} - -StorageClass Cursor::storageClass() const -{ - CXCursor cursor = m_cxCursor; - if (!isDeclaration()) - cursor = referenced().m_cxCursor; - const CX_StorageClass cxStorageClass = clang_Cursor_getStorageClass(cursor); - switch (cxStorageClass) { - case CX_SC_Invalid: - case CX_SC_OpenCLWorkGroupLocal: - break; - case CX_SC_None: - return StorageClass::None; - case CX_SC_Extern: - return StorageClass::Extern; - case CX_SC_Static: - return StorageClass::Static; - case CX_SC_PrivateExtern: - return StorageClass::PrivateExtern; - case CX_SC_Auto: - return StorageClass::Auto; - case CX_SC_Register: - return StorageClass::Register; - } - return StorageClass::Invalid; -} - -AccessSpecifier Cursor::accessSpecifier() const -{ - CXCursor cursor = m_cxCursor; - if (!isDeclaration()) - cursor = referenced().m_cxCursor; - const CX_CXXAccessSpecifier cxAccessSpecifier = clang_getCXXAccessSpecifier(cursor); - switch (cxAccessSpecifier) { - case CX_CXXInvalidAccessSpecifier: - break; - case CX_CXXPublic: - return AccessSpecifier::Public; - case CX_CXXProtected: - return AccessSpecifier::Protected; - case CX_CXXPrivate: - return AccessSpecifier::Private; - } - return AccessSpecifier::Invalid; -} - -bool operator==(const Cursor &first, const Cursor &second) -{ - return clang_equalCursors(first.m_cxCursor, second.m_cxCursor); -} - -bool operator!=(const Cursor &first, const Cursor &second) -{ - return !(first == second); -} - -std::ostream &operator<<(std::ostream &os, CXCursorKind cursorKind) -{ - ClangString cursorKindSpelling(clang_getCursorKindSpelling(cursorKind)); - return os << cursorKindSpelling.cString(); -} - -std::ostream &operator<<(std::ostream &os, const Cursor &cursor) -{ - if (cursor.isValid()) { - ClangString cursorKindSpelling(clang_getCursorKindSpelling(cursor.kind())); - os << cursorKindSpelling << " "; - - auto identifier = cursor.displayName(); - if (identifier.hasContent()) { - os << "\"" - << identifier - << "\": "; - } - - os << cursor.sourceLocation(); - } else { - os << "Invalid cursor!"; - } - - return os; -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/cursor.h b/src/tools/clangbackend/source/cursor.h deleted file mode 100644 index fe9641ecfe..0000000000 --- a/src/tools/clangbackend/source/cursor.h +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangtype.h" - -#include <clangsupport/clangsupport_global.h> - -#include <clang-c/Index.h> - -#include <iosfwd> - -#include <vector> - -namespace ClangBackEnd { - -class SourceLocation; -class SourceRange; -class ClangString; - -class Cursor -{ - friend class Type; - friend bool operator==(const Cursor &first, const Cursor &second); -public: - Cursor(); - Cursor(CXCursor cxCursor); - - bool isNull() const; - bool isValid() const; - - bool isTranslationUnit() const; - bool isDefinition() const; - bool isDynamicCall() const; - bool isVirtualMethod() const; - bool isPureVirtualMethod() const; - bool isConstantMethod() const; - bool isStaticMethod() const; - bool isCompoundType() const; - bool isDeclaration() const; - bool isInvalidDeclaration() const; - bool isParameter() const; - bool isLocalVariable() const; - bool isReference() const; - bool isExpression() const; - bool isFunctionLike() const; - bool isConstructorOrDestructor() const; - bool isTemplateLike() const; - bool isAnyTypeAlias() const; - bool hasFinalFunctionAttribute() const; - bool hasFinalClassAttribute() const; - bool isUnexposed() const; - bool isAnonymous() const; - - Utf8String displayName() const; - ClangString unifiedSymbolResolution() const; - ClangString mangling() const; - ClangString spelling() const; - ClangString briefComment() const; - Utf8String rawComment() const; - int argumentCount() const; - - Type type() const; - Type nonPointerTupe() const; - Type enumType() const; - - long long enumConstantValue() const; - unsigned long long enumConstantUnsignedValue() const; - - SourceLocation sourceLocation() const; - CXSourceLocation cxSourceLocation() const; - SourceRange sourceRange() const; - CXSourceRange cxSourceRange() const; - CXTranslationUnit cxTranslationUnit() const; - SourceRange commentRange() const; - bool hasSameSourceLocationAs(const Cursor &other) const; - - Cursor definition() const; - Cursor canonical() const; - Cursor referenced() const; - Cursor semanticParent() const; - Cursor lexicalParent() const; - Cursor functionBaseDeclaration() const; - Cursor functionBase() const; - Type resultType() const; - Cursor argument(int index) const; - unsigned overloadedDeclarationsCount() const; - Cursor overloadedDeclaration(unsigned index) const; - Cursor specializedCursorTemplate() const; - AccessSpecifier accessSpecifier() const; - StorageClass storageClass() const; - - CXFile includedFile() const; - - void collectOutputArgumentRangesTo( - std::vector<CXSourceRange> &outputArgumentRanges) const; - std::vector<CXSourceRange> outputArgumentRanges() const; - - CXCursorKind kind() const; - - template <class VisitorCallback> - void visit(VisitorCallback visitorCallback) const; - - CXCursor cx() const; - -private: - CXCursor m_cxCursor; -}; - -template <class VisitorCallback> -void Cursor::visit(VisitorCallback visitorCallback) const -{ - auto visitor = [] (CXCursor cursor, CXCursor parent, CXClientData lambda) -> CXChildVisitResult { - auto &visitorCallback = *static_cast<VisitorCallback*>(lambda); - - return visitorCallback(cursor, parent); - }; - - clang_visitChildren(m_cxCursor, visitor, &visitorCallback); -} - -bool operator==(const Cursor &first, const Cursor &second); -bool operator!=(const Cursor &first, const Cursor &second); - -std::ostream &operator<<(std::ostream &os, CXCursorKind cursorKind); -std::ostream &operator<<(std::ostream &os, const Cursor &cursor); - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/diagnostic.cpp b/src/tools/clangbackend/source/diagnostic.cpp deleted file mode 100644 index b7bcf5b02f..0000000000 --- a/src/tools/clangbackend/source/diagnostic.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "diagnostic.h" - -#include "clangstring.h" -#include "diagnosticset.h" -#include "fixit.h" -#include "sourcelocation.h" -#include "sourcerange.h" - -#include <diagnosticcontainer.h> -#include <memory> - -namespace ClangBackEnd { - -Diagnostic::Diagnostic(CXTranslationUnit translationUnit, CXDiagnostic cxDiagnostic) - : cxDiagnostic(cxDiagnostic), - cxTranslationUnit(translationUnit) -{ -} - -Diagnostic::~Diagnostic() -{ - clang_disposeDiagnostic(cxDiagnostic); -} - -Diagnostic::Diagnostic(Diagnostic &&other) - : cxDiagnostic(std::move(other.cxDiagnostic)), - cxTranslationUnit(std::move(other.cxTranslationUnit)) -{ - other.cxDiagnostic = nullptr; - other.cxTranslationUnit = nullptr; -} - -Diagnostic &Diagnostic::operator=(Diagnostic &&other) -{ - if (this != &other) { - clang_disposeDiagnostic(cxDiagnostic); - cxDiagnostic = std::move(other.cxDiagnostic); - cxTranslationUnit = std::move(other.cxTranslationUnit); - other.cxDiagnostic = nullptr; - other.cxTranslationUnit = nullptr; - } - - return *this; -} - -bool Diagnostic::isNull() const -{ - return cxDiagnostic == nullptr; -} - -Utf8String Diagnostic::text() const -{ - return ClangString(clang_formatDiagnostic(cxDiagnostic, 0)); -} - -Utf8String Diagnostic::category() const -{ - return ClangString(clang_getDiagnosticCategoryText(cxDiagnostic)); -} - -std::pair<Utf8String, Utf8String> Diagnostic::options() const -{ - CXString disableString; - - const Utf8String enableOption = ClangString(clang_getDiagnosticOption(cxDiagnostic, &disableString)); - const Utf8String disableOption = ClangString(disableString); - - return {enableOption, disableOption}; -} - -SourceLocation Diagnostic::location() const -{ - return {cxTranslationUnit, clang_getDiagnosticLocation(cxDiagnostic)}; -} - -DiagnosticSeverity Diagnostic::severity() const -{ - return static_cast<DiagnosticSeverity>(clang_getDiagnosticSeverity(cxDiagnostic)); -} - -std::vector<SourceRange> Diagnostic::ranges() const -{ - std::vector<SourceRange> ranges; - const uint rangesCount = clang_getDiagnosticNumRanges(cxDiagnostic); - ranges.reserve(rangesCount); - - for (uint index = 0; index < rangesCount; ++index) { - const SourceRange sourceRange {cxTranslationUnit, - clang_getDiagnosticRange(cxDiagnostic, index)}; - - if (sourceRange.isValid()) - ranges.push_back(std::move(sourceRange)); - } - - return ranges; -} - -std::vector<FixIt> Diagnostic::fixIts() const -{ - std::vector<FixIt> fixIts; - - const uint fixItsCount = clang_getDiagnosticNumFixIts(cxDiagnostic); - - fixIts.reserve(fixItsCount); - - for (uint index = 0; index < fixItsCount; ++index) - fixIts.push_back(FixIt(cxTranslationUnit, cxDiagnostic, index)); - - return fixIts; -} - -DiagnosticSet Diagnostic::childDiagnostics() const -{ - return DiagnosticSet(cxTranslationUnit, clang_getChildDiagnostics(cxDiagnostic)); -} - -DiagnosticContainer Diagnostic::toDiagnosticContainer() const -{ - return DiagnosticContainer(text(), - category(), - options(), - severity(), - location().toSourceLocationContainer(), - getSourceRangeContainers(), - getFixItContainers(), - childDiagnostics().toDiagnosticContainers()); -} - -QVector<SourceRangeContainer> Diagnostic::getSourceRangeContainers() const -{ - auto rangeVector = ranges(); - - QVector<SourceRangeContainer> sourceRangeContainers; - sourceRangeContainers.reserve(int(rangeVector.size())); - - for (auto &&sourceRange : rangeVector) - sourceRangeContainers.push_back(sourceRange.toSourceRangeContainer()); - - return sourceRangeContainers; -} - -QVector<FixItContainer> Diagnostic::getFixItContainers() const -{ - auto fixItVector = fixIts(); - - QVector<FixItContainer> fixItContainers; - fixItContainers.reserve(int(fixItVector.size())); - - for (auto &&fixIt : fixItVector) - fixItContainers.push_back(fixIt.toFixItContainer()); - - return fixItContainers; -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/diagnostic.h b/src/tools/clangbackend/source/diagnostic.h deleted file mode 100644 index a71ac5afa8..0000000000 --- a/src/tools/clangbackend/source/diagnostic.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <clangsupport_global.h> - -#include <QVector> - -#include <clang-c/Index.h> - -#include <functional> -#include <vector> - -class Utf8String; - -namespace ClangBackEnd { - -class SourceLocation; -class SourceRange; -class FixIt; -class DiagnosticSet; -class DiagnosticContainer; -class SourceRangeContainer; -class FixItContainer; - -class Diagnostic -{ - friend class DiagnosticSet; - friend class DiagnosticSetIterator; - friend bool operator==(Diagnostic first, Diagnostic second); - -public: - ~Diagnostic(); - - Diagnostic(const Diagnostic &) = delete; - const Diagnostic &operator=(const Diagnostic &) = delete; - - Diagnostic(Diagnostic &&other); - Diagnostic &operator=(Diagnostic &&other); - - bool isNull() const; - - Utf8String text() const; - Utf8String category() const; - std::pair<Utf8String, Utf8String> options() const; - SourceLocation location() const; - DiagnosticSeverity severity() const; - std::vector<SourceRange> ranges() const; - std::vector<FixIt> fixIts() const; - DiagnosticSet childDiagnostics() const; - - DiagnosticContainer toDiagnosticContainer() const; - -private: - Diagnostic(CXTranslationUnit translationUnit, CXDiagnostic cxDiagnostic); - QVector<SourceRangeContainer> getSourceRangeContainers() const; - QVector<FixItContainer> getFixItContainers() const; - -private: - CXDiagnostic cxDiagnostic; - CXTranslationUnit cxTranslationUnit; -}; - -inline bool operator==(Diagnostic first, Diagnostic second) -{ - return first.cxDiagnostic == second.cxDiagnostic; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/diagnosticset.cpp b/src/tools/clangbackend/source/diagnosticset.cpp deleted file mode 100644 index 39c8255137..0000000000 --- a/src/tools/clangbackend/source/diagnosticset.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "diagnosticset.h" - -#include "diagnostic.h" - -#include <diagnosticcontainer.h> - -#include <memory> - -namespace ClangBackEnd { - -DiagnosticSet::DiagnosticSet(CXTranslationUnit translationUnit, CXDiagnosticSet cxDiagnosticSet) - : cxDiagnosticSet(cxDiagnosticSet), - cxTranslationUnit(translationUnit) -{ -} - -DiagnosticSet::~DiagnosticSet() -{ - clang_disposeDiagnosticSet(cxDiagnosticSet); -} - -DiagnosticSet::DiagnosticSet(DiagnosticSet &&other) - : cxDiagnosticSet(std::move(other.cxDiagnosticSet)), - cxTranslationUnit(std::move(other.cxTranslationUnit)) -{ - other.cxDiagnosticSet = nullptr; -} - -DiagnosticSet &DiagnosticSet::operator=(DiagnosticSet &&other) -{ - if (this != &other) { - clang_disposeDiagnosticSet(cxDiagnosticSet); - cxDiagnosticSet = std::move(other.cxDiagnosticSet); - cxTranslationUnit = std::move(other.cxTranslationUnit); - other.cxDiagnosticSet = nullptr; - other.cxTranslationUnit = nullptr; - } - - return *this; -} - -Diagnostic DiagnosticSet::front() const -{ - return Diagnostic(cxTranslationUnit, clang_getDiagnosticInSet(cxDiagnosticSet, 0)); -} - -Diagnostic DiagnosticSet::back() const -{ - return Diagnostic(cxTranslationUnit, clang_getDiagnosticInSet(cxDiagnosticSet, size() - 1)); -} - -DiagnosticSet::ConstIterator DiagnosticSet::begin() const -{ - return DiagnosticSetIterator(cxTranslationUnit, cxDiagnosticSet, 0); -} - -DiagnosticSet::ConstIterator DiagnosticSet::end() const -{ - return DiagnosticSetIterator(cxTranslationUnit, cxDiagnosticSet, size()); -} - -QVector<DiagnosticContainer> DiagnosticSet::toDiagnosticContainers() const -{ - const auto isAcceptedDiagnostic = [](const Diagnostic &) { return true; }; - - return toDiagnosticContainers(isAcceptedDiagnostic); -} - -QVector<DiagnosticContainer> DiagnosticSet::toDiagnosticContainers( - const IsAcceptedDiagnostic &isAcceptedDiagnostic) const -{ - QVector<DiagnosticContainer> diagnosticContainers; - diagnosticContainers.reserve(size()); - - for (const Diagnostic &diagnostic : *this) { - if (isAcceptedDiagnostic(diagnostic)) - diagnosticContainers.push_back(diagnostic.toDiagnosticContainer()); - } - - return diagnosticContainers; -} - -uint DiagnosticSet::size() const -{ - return clang_getNumDiagnosticsInSet(cxDiagnosticSet); -} - -bool DiagnosticSet::isNull() const -{ - return cxDiagnosticSet == nullptr; -} - -Diagnostic DiagnosticSet::at(uint index) const -{ - return Diagnostic(cxTranslationUnit, clang_getDiagnosticInSet(cxDiagnosticSet, index)); -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/diagnosticset.h b/src/tools/clangbackend/source/diagnosticset.h deleted file mode 100644 index 63f672de41..0000000000 --- a/src/tools/clangbackend/source/diagnosticset.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "diagnostic.h" -#include "diagnosticsetiterator.h" - -#include <clang-c/Index.h> - -#include <QVector> - -#include <functional> - -namespace ClangBackEnd { - -class DiagnosticSetIterator; - -class DiagnosticSet -{ - friend class TranslationUnit; - friend class Diagnostic; - -public: - using ConstIterator = DiagnosticSetIterator; - -public: - ~DiagnosticSet(); - - DiagnosticSet(const DiagnosticSet &) = delete; - const DiagnosticSet &operator=(const DiagnosticSet &) = delete; - - DiagnosticSet(DiagnosticSet &&other); - DiagnosticSet &operator=(DiagnosticSet &&other); - - uint size() const; - bool isNull() const; - - Diagnostic at(uint index) const; - - Diagnostic front() const; - Diagnostic back() const; - - ConstIterator begin() const; - ConstIterator end() const; - - using IsAcceptedDiagnostic = std::function<bool (const Diagnostic &)>; - QVector<DiagnosticContainer> toDiagnosticContainers() const; - QVector<DiagnosticContainer> toDiagnosticContainers( - const IsAcceptedDiagnostic &isAcceptedDiagnostic) const; - -private: - DiagnosticSet(CXTranslationUnit translationUnit, CXDiagnosticSet cxDiagnosticSet); - -private: - CXDiagnosticSet cxDiagnosticSet; - CXTranslationUnit cxTranslationUnit; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/diagnosticsetiterator.h b/src/tools/clangbackend/source/diagnosticsetiterator.h deleted file mode 100644 index eb1ceac7a0..0000000000 --- a/src/tools/clangbackend/source/diagnosticsetiterator.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "diagnostic.h" - -#include <iterator> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -using uint = unsigned int; - -class DiagnosticSet; - -class DiagnosticSetIterator -{ -public: - using iterator_category = std::random_access_iterator_tag; - using value_type = Diagnostic; - using difference_type = uint; - using pointer = Diagnostic *; - using reference = Diagnostic &; - - DiagnosticSetIterator(CXTranslationUnit translationUnit, - CXDiagnosticSet cxDiagnosticSet, - uint index) - : cxDiagnosticSet(cxDiagnosticSet), - cxTranslationUnit(translationUnit), - index(index) - {} - - DiagnosticSetIterator(const DiagnosticSetIterator &other) - : cxDiagnosticSet(other.cxDiagnosticSet), - index(other.index) - {} - - DiagnosticSetIterator& operator++() - { - ++index; - return *this; - } - - DiagnosticSetIterator operator++(int) - { - uint oldIndex = index++; - return DiagnosticSetIterator(cxTranslationUnit, cxDiagnosticSet, oldIndex); - } - - bool operator==(const DiagnosticSetIterator &other) const - { - return index == other.index && cxDiagnosticSet == other.cxDiagnosticSet; - } - - bool operator!=(const DiagnosticSetIterator &other) const - { - return index != other.index || cxDiagnosticSet != other.cxDiagnosticSet; - } - - Diagnostic operator*() - { - return Diagnostic(cxTranslationUnit, clang_getDiagnosticInSet(cxDiagnosticSet, index)); - } - -private: - CXDiagnosticSet cxDiagnosticSet; - CXTranslationUnit cxTranslationUnit; - uint index; -}; - -} diff --git a/src/tools/clangbackend/source/fixit.cpp b/src/tools/clangbackend/source/fixit.cpp deleted file mode 100644 index 8626602d45..0000000000 --- a/src/tools/clangbackend/source/fixit.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "fixit.h" - -#include "clangstring.h" - -#include <fixitcontainer.h> - -namespace ClangBackEnd { - -const Utf8String &FixIt::text() const -{ - return text_; -} - -const SourceRange &FixIt::range() const -{ - return sourceRange; -} - -FixItContainer FixIt::toFixItContainer() const -{ - return FixItContainer(text_, sourceRange.toSourceRangeContainer()); -} - -FixIt::FixIt(CXTranslationUnit translationUnit, CXDiagnostic cxDiagnostic, uint index) -{ - CXSourceRange cxSourceRange; - - text_ = ClangString(clang_getDiagnosticFixIt(cxDiagnostic, index, &cxSourceRange)); - sourceRange = SourceRange(translationUnit, cxSourceRange); -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/fixit.h b/src/tools/clangbackend/source/fixit.h deleted file mode 100644 index b0c1f139ae..0000000000 --- a/src/tools/clangbackend/source/fixit.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "sourcerange.h" - -#include <utf8string.h> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -class FixItContainer; - -using uint = unsigned int; - -class FixIt -{ - friend class Diagnostic; -public: - const Utf8String &text() const; - const SourceRange &range() const; - - FixItContainer toFixItContainer() const; - -private: - FixIt(CXTranslationUnit translationUnit, CXDiagnostic cxDiagnostic, uint index); - -private: - SourceRange sourceRange; - Utf8String text_; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/fulltokeninfo.cpp b/src/tools/clangbackend/source/fulltokeninfo.cpp deleted file mode 100644 index 58b8398c97..0000000000 --- a/src/tools/clangbackend/source/fulltokeninfo.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangstring.h" -#include "clangtooltipinfocollector.h" -#include "cursor.h" -#include "fulltokeninfo.h" -#include "sourcerange.h" -#include "token.h" -#include "tokenprocessor.h" - -#include <utils/predicates.h> - -namespace ClangBackEnd { - -FullTokenInfo::FullTokenInfo(const Cursor &cursor, - const Token *token, - std::vector<CXSourceRange> ¤tOutputArgumentRanges) - : TokenInfo(cursor, token, currentOutputArgumentRanges) -{ -} - -FullTokenInfo::operator TokenInfoContainer() const -{ - return TokenInfoContainer(line(), column(), length(), m_types, m_extraInfo); -} - -static Utf8String fullyQualifiedType(const Cursor &cursor) { - Utf8String prefix; - if (cursor.kind() == CXCursor_ClassTemplate || cursor.kind() == CXCursor_Namespace) - return qualificationPrefix(cursor) + cursor.displayName(); - - return cursor.type().canonical().spelling(); -} - -void FullTokenInfo::updateTypeSpelling(const Cursor &cursor, bool functionLike) -{ - m_extraInfo.semanticParentTypeSpelling = fullyQualifiedType(cursor.semanticParent()); - if (!functionLike) { - m_extraInfo.typeSpelling = fullyQualifiedType(cursor); - return; - } - - m_extraInfo.token = cursor.displayName(); - // On the client side full type is typeSpelling + token. - m_extraInfo.typeSpelling = cursor.type().resultType().utf8Spelling(); -} - -static Utf8String propertyParentSpelling(CXTranslationUnit cxTranslationUnit, - const Utf8String &filePath, - uint line, uint column) -{ - // Q_PROPERTY expands into QPropertyMagicFunction which can be found as a child of - // the containing class. - Cursor tuCursor = clang_getTranslationUnitCursor(cxTranslationUnit); - Utf8String parentSpelling; - tuCursor.visit([&filePath, line, column, &parentSpelling](CXCursor cxCursor, CXCursor parent) { - const CXCursorKind kind = clang_getCursorKind(cxCursor); - if (kind == CXCursor_Namespace || kind == CXCursor_StructDecl - || kind == CXCursor_ClassDecl || kind == CXCursor_StaticAssert) { - Cursor cursor(cxCursor); - const SourceRange range = cursor.sourceRange(); - if (range.start().filePath() != filePath) - return CXChildVisit_Continue; - if (range.contains(line, column)) { - if (kind == CXCursor_Namespace || kind == CXCursor_StructDecl - || kind == CXCursor_ClassDecl) { - return CXChildVisit_Recurse; - } - // CXCursor_StaticAssert case. This is Q_PROPERTY static_assert - parentSpelling = Cursor(parent).type().spelling(); - return CXChildVisit_Break; - } - } - return CXChildVisit_Continue; - }); - return parentSpelling; -} - -static Utf8String getPropertyType(const SourceLocation &location, uint propertyPosition) -{ - // Extract property type from the source code - CXFile cxFile; - uint offset; - clang_getFileLocation(location.cx(), &cxFile, nullptr, nullptr, &offset); - const char *const contents = clang_getFileContents(location.tu(), cxFile, nullptr); - const int keywordOffset = QByteArray::fromRawData(contents, propertyPosition) - .lastIndexOf("Q_PROPERTY"); - if (keywordOffset == -1) - return {}; - const char * const keywordStart = contents + keywordOffset; - const char *typeStart = keywordStart + 10; - typeStart += std::strspn(typeStart, "( \t\n\r"); - if (typeStart - keywordStart >= propertyPosition) - return Utf8String(); - auto typeEnd = std::find_if(std::reverse_iterator<const char*>(keywordStart + propertyPosition), - std::reverse_iterator<const char*>(typeStart), - Utils::unequalTo(' ')); - - return Utf8String(typeStart, static_cast<int>(&(*typeEnd) + 1 - typeStart)); -} - -void FullTokenInfo::updatePropertyData() -{ - const SourceRange range = m_token->extent(); - m_extraInfo.semanticParentTypeSpelling = propertyParentSpelling(m_token->tu(), - range.start().filePath(), - line(), - column()); - m_extraInfo.cursorRange = range; - m_extraInfo.declaration = true; - m_extraInfo.definition = true; - m_extraInfo.typeSpelling = getPropertyType(range.start(), column() - 1); -} - -void FullTokenInfo::identifierKind(const Cursor &cursor, Recursion recursion) -{ - updateTypeSpelling(cursor); - - TokenInfo::identifierKind(cursor, recursion); - - m_extraInfo.identifier = (cursor.kind() != CXCursor_PreprocessingDirective); - - if (m_types.mainHighlightingType == HighlightingType::QtProperty) - updatePropertyData(); - else - m_extraInfo.cursorRange = cursor.sourceRange(); -} - -void FullTokenInfo::referencedTypeKind(const Cursor &cursor) -{ - updateTypeSpelling(cursor.referenced()); - - TokenInfo::referencedTypeKind(cursor); -} - -void FullTokenInfo::functionKind(const Cursor &cursor, Recursion recursion) -{ - updateTypeSpelling(cursor, true); - - TokenInfo::functionKind(cursor, recursion); - - m_extraInfo.accessSpecifier = cursor.accessSpecifier(); - m_extraInfo.storageClass = cursor.storageClass(); - - bool isSignal = false; - bool isSlot = false; - m_originalCursor.visit([&isSignal, &isSlot](CXCursor cursor, CXCursor) { - Cursor cur(cursor); - ClangString spelling = cur.spelling(); - if (spelling == "qt_signal") - isSignal = true; - else if (spelling == "qt_slot") - isSlot = true; - return CXChildVisit_Break; - }); - m_extraInfo.signal = isSignal; - m_extraInfo.slot = isSlot; -} - -void FullTokenInfo::variableKind(const Cursor &cursor) -{ - TokenInfo::variableKind(cursor); - - m_extraInfo.accessSpecifier = cursor.accessSpecifier(); - m_extraInfo.storageClass = cursor.storageClass(); -} - -void FullTokenInfo::fieldKind(const Cursor &cursor) -{ - TokenInfo::fieldKind(cursor); - - m_extraInfo.accessSpecifier = cursor.accessSpecifier(); - m_extraInfo.storageClass = cursor.storageClass(); -} - -void FullTokenInfo::memberReferenceKind(const Cursor &cursor) -{ - TokenInfo::memberReferenceKind(cursor); - if (cursor.isDynamicCall()) { - m_extraInfo.storageClass = cursor.storageClass(); - m_extraInfo.accessSpecifier = cursor.accessSpecifier(); - } -} - -void FullTokenInfo::keywordKind() -{ - TokenInfo::keywordKind(); - - if (m_originalCursor.isAnonymous()) { - CXCursorKind cursorKind = m_originalCursor.kind(); - if (cursorKind == CXCursor_EnumDecl) - m_types.mixinHighlightingTypes.push_back(HighlightingType::Enum); - else if (cursorKind == CXCursor_ClassDecl) - m_types.mixinHighlightingTypes.push_back(HighlightingType::Class); - else if (cursorKind == CXCursor_StructDecl) - m_types.mixinHighlightingTypes.push_back(HighlightingType::Struct); - else if (cursorKind == CXCursor_Namespace) - m_types.mixinHighlightingTypes.push_back(HighlightingType::Namespace); - m_extraInfo.declaration = m_extraInfo.definition = true; - m_extraInfo.token = m_originalCursor.displayName(); - updateTypeSpelling(m_originalCursor); - m_extraInfo.cursorRange = m_originalCursor.sourceRange(); - } -} - -void FullTokenInfo::overloadedOperatorKind() -{ - TokenInfo::overloadedOperatorKind(); - - if (!m_types.mixinHighlightingTypes.contains(HighlightingType::OverloadedOperator)) - return; - - // Overloaded operator - m_extraInfo.identifier = true; - if (!m_originalCursor.isDeclaration()) - return; - - // Overloaded operator declaration - m_extraInfo.declaration = true; - m_extraInfo.definition = m_originalCursor.isDefinition(); - - updateTypeSpelling(m_originalCursor, true); - m_extraInfo.cursorRange = m_originalCursor.sourceRange(); - m_extraInfo.accessSpecifier = m_originalCursor.accessSpecifier(); - m_extraInfo.storageClass = m_originalCursor.storageClass(); -} - -void FullTokenInfo::evaluate() -{ - m_extraInfo.token = m_token->spelling(); - CXTokenKind cxTokenKind = m_token->kind(); - if (cxTokenKind == CXToken_Identifier) { - m_extraInfo.declaration = m_originalCursor.isDeclaration(); - m_extraInfo.definition = m_originalCursor.isDefinition(); - } - m_extraInfo.includeDirectivePath = (m_originalCursor.kind() == CXCursor_InclusionDirective); - - TokenInfo::evaluate(); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/fulltokeninfo.h b/src/tools/clangbackend/source/fulltokeninfo.h deleted file mode 100644 index 96e374c905..0000000000 --- a/src/tools/clangbackend/source/fulltokeninfo.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "tokeninfo.h" - -namespace ClangBackEnd { - -class FullTokenInfo : public TokenInfo -{ - template<class T> friend class TokenProcessor; -public: - FullTokenInfo() = default; - FullTokenInfo(const Cursor &cursor, - const Token *token, - std::vector<CXSourceRange> &m_currentOutputArgumentRanges); - void evaluate() override; - - operator TokenInfoContainer() const override; -protected: - void identifierKind(const Cursor &cursor, Recursion recursion) override; - void referencedTypeKind(const Cursor &cursor) override; - void functionKind(const Cursor &cursor, Recursion recursion) override; - void variableKind(const Cursor &cursor) override; - void fieldKind(const Cursor &cursor) override; - void memberReferenceKind(const Cursor &cursor) override; - void keywordKind() override; - void overloadedOperatorKind() override; -private: - void updateTypeSpelling(const Cursor &cursor, bool functionLike = false); - void updatePropertyData(); - - ExtraInfo m_extraInfo; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/skippedsourceranges.cpp b/src/tools/clangbackend/source/skippedsourceranges.cpp deleted file mode 100644 index 83384fcc53..0000000000 --- a/src/tools/clangbackend/source/skippedsourceranges.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "skippedsourceranges.h" - -#include "sourcerangecontainer.h" - -#include <QVector> - -#include <algorithm> - -namespace ClangBackEnd { - -SkippedSourceRanges::SkippedSourceRanges(CXTranslationUnit cxTranslationUnit, const char *filePath) - : cxTranslationUnit(cxTranslationUnit) - , cxSkippedSourceRanges(clang_getSkippedRanges(cxTranslationUnit, - clang_getFile(cxTranslationUnit, filePath))) -{ -} - -SkippedSourceRanges::~SkippedSourceRanges() -{ - clang_disposeSourceRangeList(cxSkippedSourceRanges); -} - -SkippedSourceRanges &SkippedSourceRanges::operator=(SkippedSourceRanges &&other) -{ - if (this != &other) { - this->~SkippedSourceRanges(); - cxTranslationUnit = other.cxTranslationUnit; - cxSkippedSourceRanges = other.cxSkippedSourceRanges; - other.cxTranslationUnit = nullptr; - other.cxSkippedSourceRanges = nullptr; - } - - return *this; -} - -// For some reason, libclang starts the skipped range on the line containing the -// preprocessor directive preceding the ifdef'ed out code (i.e. #if or #else) -// and ends it on the line following the ifdef'ed out code (#else or #endif, respectively). -// We don't want the preprocessor directives grayed out, so adapt the locations. -static SourceRange adaptedSourceRange(CXTranslationUnit cxTranslationUnit, const SourceRange &range) -{ - const SourceLocation end = range.end(); - - return SourceRange { - SourceLocation(cxTranslationUnit, - clang_getLocation(cxTranslationUnit, - clang_getFile(cxTranslationUnit, - end.filePath().constData()), - range.start().line() + 1, 1)), - SourceLocation(cxTranslationUnit, - clang_getLocation(cxTranslationUnit, - clang_getFile(cxTranslationUnit, - end.filePath().constData()), - end.line(), 1)) - }; -} - -// TODO: This should report a line range. -std::vector<SourceRange> SkippedSourceRanges::sourceRanges() const -{ - std::vector<SourceRange> sourceRanges; - - auto sourceRangeCount = cxSkippedSourceRanges->count; - sourceRanges.reserve(sourceRangeCount); - - for (uint i = 0; i < cxSkippedSourceRanges->count; ++i) { - const SourceRange range {cxTranslationUnit, cxSkippedSourceRanges->ranges[i]}; - const SourceRange adaptedRange = adaptedSourceRange(cxTranslationUnit, range); - - sourceRanges.push_back(adaptedRange); - } - - return sourceRanges; -} - -QVector<SourceRangeContainer> SkippedSourceRanges::toSourceRangeContainers() const -{ - QVector<SourceRangeContainer> sourceRangeContainers; - - auto sourceRanges = this->sourceRanges(); - - std::copy(sourceRanges.cbegin(), - sourceRanges.cend(), - std::back_inserter(sourceRangeContainers)); - - return sourceRangeContainers; -} - -bool SkippedSourceRanges::isNull() const -{ - - return cxTranslationUnit == nullptr || cxSkippedSourceRanges == nullptr; -} - -ClangBackEnd::SkippedSourceRanges::operator QVector<SourceRangeContainer>() const -{ - return toSourceRangeContainers(); -} - -SkippedSourceRanges::SkippedSourceRanges(SkippedSourceRanges &&other) - : cxTranslationUnit(other.cxTranslationUnit) - , cxSkippedSourceRanges(other.cxSkippedSourceRanges) -{ - other.cxTranslationUnit = nullptr; - other.cxSkippedSourceRanges = nullptr; -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/skippedsourceranges.h b/src/tools/clangbackend/source/skippedsourceranges.h deleted file mode 100644 index 80bc943676..0000000000 --- a/src/tools/clangbackend/source/skippedsourceranges.h +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "sourcerange.h" - -namespace ClangBackEnd { - -class SourceRangeContainer; - -class SkippedSourceRanges -{ -public: - SkippedSourceRanges(CXTranslationUnit Document, const char *filePath); - ~SkippedSourceRanges(); - - SkippedSourceRanges(const SkippedSourceRanges &) = delete; - const SkippedSourceRanges &operator=(const SkippedSourceRanges &) = delete; - - SkippedSourceRanges(SkippedSourceRanges &&); - SkippedSourceRanges &operator=(SkippedSourceRanges &&); - - std::vector<SourceRange> sourceRanges() const; - - QVector<SourceRangeContainer> toSourceRangeContainers() const; - - bool isNull() const; - - operator QVector<SourceRangeContainer>() const; - -private: - CXTranslationUnit cxTranslationUnit = nullptr; - CXSourceRangeList *cxSkippedSourceRanges = nullptr; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/sourcelocation.cpp b/src/tools/clangbackend/source/sourcelocation.cpp deleted file mode 100644 index ad52667dd6..0000000000 --- a/src/tools/clangbackend/source/sourcelocation.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "sourcelocation.h" - -#include "clangdocument.h" -#include "clangfilepath.h" -#include "clangstring.h" - -#include <clangsupport/sourcelocationcontainer.h> - -#include <clangsupport/utf8string.h> - -#include <utils/textutils.h> - -#include <ostream> - -namespace ClangBackEnd { - -SourceLocation::SourceLocation() - : m_cxSourceLocation(clang_getNullLocation()) -{ -} - -const Utf8String &SourceLocation::filePath() const -{ - if (!m_isEvaluated) - evaluate(); - - if (m_isFilePathNormalized) - return m_filePath; - - m_isFilePathNormalized = true; - m_filePath = FilePath::fromNativeSeparators(m_filePath); - - return m_filePath; -} - -int SourceLocation::line() const -{ - if (!m_isEvaluated) - evaluate(); - return m_line; -} - -int SourceLocation::column() const -{ - if (!m_isEvaluated) - evaluate(); - return m_column; -} - -int SourceLocation::offset() const -{ - if (!m_isEvaluated) - evaluate(); - return m_offset; -} - -SourceLocationContainer SourceLocation::toSourceLocationContainer() const -{ - if (!m_isEvaluated) - evaluate(); - return SourceLocationContainer(filePath(), m_line, m_column); -} - -void SourceLocation::evaluate() const -{ - m_isEvaluated = true; - - CXFile cxFile; - - unsigned line, column, offset; - clang_getFileLocation(m_cxSourceLocation, - &cxFile, - &line, - &column, - &offset); - m_line = line; - m_column = column; - m_offset = offset; - - m_isFilePathNormalized = false; - if (!cxFile) - return; - - m_filePath = ClangString(clang_getFileName(cxFile)); - if (m_column > 1) { - const int lineStart = m_offset + 1 - m_column; - const char *contents = clang_getFileContents(m_cxTranslationUnit, cxFile, nullptr); - if (!contents) - return; - // (1) column in SourceLocation is the actual column shown by CppEditor. - // (2) column in Clang is the utf8 byte offset from the beginning of the line. - // Here we convert column from (2) to (1). - m_column = QString::fromUtf8(&contents[lineStart], m_column - 1).size() + 1; - } -} - -SourceLocation::SourceLocation(CXTranslationUnit cxTranslationUnit, - CXSourceLocation cxSourceLocation) - : m_cxSourceLocation(cxSourceLocation) - , m_cxTranslationUnit(cxTranslationUnit) -{ -} - -SourceLocation::operator CXSourceLocation() const -{ - return m_cxSourceLocation; -} - -std::ostream &operator<<(std::ostream &os, const SourceLocation &sourceLocation) -{ - auto filePath = sourceLocation.filePath(); - if (filePath.hasContent()) - os << filePath << ", "; - - os << "line: " << sourceLocation.line() - << ", column: "<< sourceLocation.column() - << ", offset: "<< sourceLocation.offset(); - - return os; -} - -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/sourcelocation.h b/src/tools/clangbackend/source/sourcelocation.h deleted file mode 100644 index 0c668c38de..0000000000 --- a/src/tools/clangbackend/source/sourcelocation.h +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <clang-c/Index.h> - -#include <utf8string.h> - -namespace ClangBackEnd { - -class SourceLocationContainer; -class Document; - -class SourceLocation -{ - friend class SourceRange; - friend class TranslationUnit; - - friend bool operator==(const SourceLocation &first, const SourceLocation &second) - { - return clang_equalLocations(first.m_cxSourceLocation, second.m_cxSourceLocation); - } - friend bool operator!=(const SourceLocation &first, const SourceLocation &second) - { - return !(first == second); - } - -public: - SourceLocation(); - SourceLocation(CXTranslationUnit cxTranslationUnit, - CXSourceLocation cxSourceLocation); - - const Utf8String &filePath() const; - int line() const; - int column() const; - int offset() const; - - SourceLocationContainer toSourceLocationContainer() const; - - CXTranslationUnit tu() const { return m_cxTranslationUnit; } - CXSourceLocation cx() const { return m_cxSourceLocation; } - -private: - operator CXSourceLocation() const; - void evaluate() const; - -private: - CXSourceLocation m_cxSourceLocation; - CXTranslationUnit m_cxTranslationUnit; - mutable Utf8String m_filePath; - mutable int m_line = 0; - mutable int m_column = 0; - mutable int m_offset = 0; - mutable bool m_isFilePathNormalized = true; - mutable bool m_isEvaluated = false; -}; - -std::ostream &operator<<(std::ostream &os, const SourceLocation &sourceLocation); - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/sourcerange.cpp b/src/tools/clangbackend/source/sourcerange.cpp deleted file mode 100644 index 7100122669..0000000000 --- a/src/tools/clangbackend/source/sourcerange.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "sourcerange.h" - -#include <sourcerangecontainer.h> - -#include <ostream> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -SourceRange::SourceRange() - : cxSourceRange(clang_getNullRange()) -{ -} - -SourceRange::SourceRange(const SourceLocation &start, const SourceLocation &end) - : cxSourceRange(clang_getRange(start, end)), - cxTranslationUnit(start.m_cxTranslationUnit) -{ -} - -bool SourceRange::isNull() const -{ - return clang_Range_isNull(cxSourceRange); -} - -bool SourceRange::isValid() const -{ - return !isNull() && start().offset() < end().offset(); -} - -SourceLocation SourceRange::start() const -{ - return {cxTranslationUnit, clang_getRangeStart(cxSourceRange)}; -} - -SourceLocation SourceRange::end() const -{ - return {cxTranslationUnit, clang_getRangeEnd(cxSourceRange)}; -} - -bool SourceRange::contains(int line, int column) const -{ - const SourceLocation start_ = start(); - const SourceLocation end_ = end(); - - if (line < start_.line() || line > end_.line()) - return false; - if (line == start_.line() && column < start_.column()) - return false; - if (line == end_.line() && column > end_.column()) - return false; - return true; -} - -SourceRangeContainer SourceRange::toSourceRangeContainer() const -{ - return SourceRangeContainer(start().toSourceLocationContainer(), - end().toSourceLocationContainer()); -} - -ClangBackEnd::SourceRange::operator SourceRangeContainer() const -{ - return toSourceRangeContainer(); -} - -ClangBackEnd::SourceRange::operator CXSourceRange() const -{ - return cxSourceRange; -} - -SourceRange::SourceRange(CXTranslationUnit translationUnit, CXSourceRange cxSourceRange) - : cxSourceRange(cxSourceRange), - cxTranslationUnit(translationUnit) -{ -} - -bool operator==(const SourceRange &first, const SourceRange &second) -{ - return clang_equalRanges(first.cxSourceRange, second.cxSourceRange); -} - -std::ostream &operator<<(std::ostream &os, const SourceRange &sourceRange) -{ - os << "[" - << sourceRange.start() << ", " - << sourceRange.end() - << "]"; - - return os; -} -} // namespace ClangBackEnd - diff --git a/src/tools/clangbackend/source/sourcerange.h b/src/tools/clangbackend/source/sourcerange.h deleted file mode 100644 index 9cef453b92..0000000000 --- a/src/tools/clangbackend/source/sourcerange.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "sourcelocation.h" - -namespace ClangBackEnd { - -class SourceRangeContainer; - -class SourceRange -{ - friend class Diagnostic; - friend class FixIt; - friend class Cursor; - friend bool operator==(const SourceRange &first, const SourceRange &second); - friend std::ostream &operator<<(std::ostream &os, const SourceRange &sourceRange); - -public: - SourceRange(); - SourceRange(CXTranslationUnit cxTranslationUnit, CXSourceRange cxSourceRange); - SourceRange(const SourceLocation &start, const SourceLocation &end); - - bool isNull() const; - bool isValid() const; - - SourceLocation start() const; - SourceLocation end() const; - - bool contains(int line, int column) const; - - SourceRangeContainer toSourceRangeContainer() const; - - operator CXSourceRange() const; - operator SourceRangeContainer() const; - - CXTranslationUnit tu() const { return cxTranslationUnit; } - -private: - CXSourceRange cxSourceRange; - CXTranslationUnit cxTranslationUnit = nullptr; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/token.cpp b/src/tools/clangbackend/source/token.cpp deleted file mode 100644 index 5fa31528ec..0000000000 --- a/src/tools/clangbackend/source/token.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - - -#include "token.h" - -#include "clangstring.h" -#include "cursor.h" -#include "sourcelocation.h" -#include "sourcerange.h" - -#include <QList> - -namespace ClangBackEnd { - -Token::Token(CXTranslationUnit cxTranslationUnit, CXToken *cxToken) - : m_cxTranslationUnit(cxTranslationUnit) - , m_cxToken(cxToken) -{ -} - -bool Token::isNull() const -{ - return !m_cxToken; -} - -CXTokenKind Token::kind() const -{ - return clang_getTokenKind(*m_cxToken); -} - -CXToken *Token::cx() const -{ - return m_cxToken; -} - -SourceLocation Token::location() const -{ - return SourceLocation(m_cxTranslationUnit, clang_getTokenLocation(m_cxTranslationUnit, *m_cxToken)); -} - -SourceRange Token::extent() const -{ - return SourceRange(m_cxTranslationUnit, clang_getTokenExtent(m_cxTranslationUnit, *m_cxToken)); -} - -ClangString Token::spelling() const -{ - return clang_getTokenSpelling(m_cxTranslationUnit, *m_cxToken); -} - -Tokens::Tokens(const SourceRange &range) - : m_cxTranslationUnit(range.tu()) -{ - CXSourceRange cxRange(range); - CXToken *cxTokens; - unsigned numTokens; - clang_tokenize(m_cxTranslationUnit, cxRange, &cxTokens, &numTokens); - - m_tokens.reserve(numTokens); - for (size_t i = 0; i < numTokens; ++i) - m_tokens.push_back(Token(m_cxTranslationUnit, cxTokens + i)); -} - -std::vector<Cursor> Tokens::annotate() const -{ - std::vector<Cursor> cursors; - if (m_tokens.empty()) - return cursors; - - std::vector<CXCursor> cxCursors; - cxCursors.resize(m_tokens.size()); - - clang_annotateTokens(m_cxTranslationUnit, m_tokens.front().cx(), m_tokens.size(), cxCursors.data()); - - // The alias declaration "using S = struct {}" results in libclang reporting the type - // of the surrounding scope (e.g. a namespace or class) for the cursor corresponding to - // the token "S" (QTCREATORBUG-24875). We need to correct this manually. - // The same goes for function attributes like "[[deprecated]]". - // TODO: Investigate whether we can fix this in libclang itself. - for (int i = 1; i < int(m_tokens.size()) - 2; ++i) { - const Token &tok = m_tokens.at(i); - if (tok.kind() != CXToken_Identifier && tok.kind() != CXToken_Keyword) - continue; - const Token &prevTok = m_tokens.at(i - 1); - const Token &nextTok = m_tokens.at(i + 1); - - // QTCREATORBUG-24875 - if (prevTok.kind() == CXToken_Keyword - && prevTok.spelling() == "using" - && nextTok.spelling() == "=" - && cxCursors.at(i).kind != CXCursor_TypeAliasDecl) { - // If the surrounding scope is a namespace, the correct type is reported for the token - // after the identifier, i.e. the "=" symbol. Otherwise, it's not reported at all, - // and we have to use the cursor after that, which should be the aliased type. - // Note that we cannot use the next cursors in the cxCursors array, because - // clang_annotateTokens() reports the surrounding scope for all of these. - CXCursor nextCursor = clang_getCursor(m_cxTranslationUnit, clang_getTokenLocation( - m_cxTranslationUnit, *nextTok.cx())); - if (nextCursor.kind != CXCursor_TypeAliasDecl) { - nextCursor = clang_getCursor(m_cxTranslationUnit, clang_getTokenLocation( - m_cxTranslationUnit, *m_tokens.at(i + 2).cx())); - } - cxCursors[i] = nextCursor; - continue; - } - - // QTCREATORBUG-24636, QTCREATORBUG-24650 - if (i >= 2) { - QList<int> setToNull; - const Token &prevPrevTok = m_tokens.at(i - 2); - if (prevTok.kind() == CXToken_Punctuation && prevTok.spelling() == "[" - && prevPrevTok.kind() == CXToken_Punctuation && prevPrevTok.spelling() == "[") { - - int endOfAttrList = i + 2; // assume the first possible end of attribute declaration - while (endOfAttrList < int(m_tokens.size())) { - const Token &last = m_tokens.at(endOfAttrList); - const Token &secondLast = m_tokens.at(endOfAttrList - 1); - const Token ¤t = m_tokens.at(endOfAttrList - 2); - - if (current.kind() == CXToken_Identifier || current.kind() == CXToken_Keyword) - setToNull.append(endOfAttrList - 2); - if (last.kind() == CXToken_Punctuation && last.spelling() == "]" - && secondLast.kind() == CXToken_Punctuation - && secondLast.spelling() == "]") { - break; - } - ++endOfAttrList; - } - for (int index : qAsConst(setToNull)) { - for (int j = index + 3; j < int(m_tokens.size()); ++j) { - if (cxCursors[j] == cxCursors[j - 1]) - continue; - if (cxCursors[j].kind == CXCursor_FunctionDecl - || cxCursors[j].kind == CXCursor_ParmDecl) { - cxCursors[index] = clang_getNullCursor(); - cxCursors[index].kind = CXCursor_NotImplemented; // Our magic tag. - } - break; - } - } - } - } - } - - cursors.reserve(cxCursors.size()); - for (const CXCursor &cxCursor : cxCursors) - cursors.emplace_back(cxCursor); - - return cursors; -} - -const Token &Tokens::operator[](int index) const -{ - return m_tokens[index]; -} - -Token &Tokens::operator[](int index) -{ - return m_tokens[index]; -} - -std::vector<Token>::const_iterator Tokens::cbegin() const -{ - return m_tokens.cbegin(); -} - -std::vector<Token>::const_iterator Tokens::cend() const -{ - return m_tokens.cend(); -} - -std::vector<Token>::iterator Tokens::begin() -{ - return m_tokens.begin(); -} - -std::vector<Token>::iterator Tokens::end() -{ - return m_tokens.end(); -} - -int Tokens::getTokenIndex(CXTranslationUnit tu, uint line, uint column) const -{ - int tokenIndex = -1; - for (int i = size() - 1; i >= 0; --i) { - const SourceRange range(tu, (*this)[i].extent()); - if (range.contains(line, column)) { - tokenIndex = i; - break; - } - } - return tokenIndex; -} - -Tokens::~Tokens() -{ - if (m_tokens.empty()) - return; - - clang_disposeTokens(m_cxTranslationUnit, m_tokens.front().cx(), - static_cast<unsigned>(m_tokens.size())); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/token.h b/src/tools/clangbackend/source/token.h deleted file mode 100644 index 46635c4001..0000000000 --- a/src/tools/clangbackend/source/token.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <utils/smallstringfwd.h> - -#include <clang-c/Index.h> - -#include <vector> - -namespace ClangBackEnd { - -class ClangString; -class Cursor; -class SourceLocation; -class SourceRange; - -class Token -{ - friend class Tokens; -public: - bool isNull() const; - - CXTokenKind kind() const; - - SourceLocation location() const; - SourceRange extent() const; - ClangString spelling() const; - - CXToken *cx() const; - CXTranslationUnit tu() const { return m_cxTranslationUnit; } - -private: - Token(CXTranslationUnit m_cxTranslationUnit, CXToken *cxToken); - - CXTranslationUnit m_cxTranslationUnit; - CXToken *m_cxToken; -}; - -class Tokens -{ -public: - Tokens() = default; - Tokens(const SourceRange &range); - ~Tokens(); - - Tokens(Tokens &&other) = default; - Tokens(const Tokens &other) = delete; - Tokens &operator=(Tokens &&other) = default; - Tokens &operator=(const Tokens &other) = delete; - - std::vector<Cursor> annotate() const; - - int size() const { return static_cast<int>(m_tokens.size()); } - const Token &operator[](int index) const; - Token &operator[](int index); - - std::vector<Token>::const_iterator cbegin() const; - std::vector<Token>::const_iterator cend() const; - std::vector<Token>::iterator begin(); - std::vector<Token>::iterator end(); - - int getTokenIndex(CXTranslationUnit tu, uint line, uint column) const; - - CXTranslationUnit tu() const { return m_cxTranslationUnit; } -private: - CXTranslationUnit m_cxTranslationUnit; - std::vector<Token> m_tokens; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/tokeninfo.cpp b/src/tools/clangbackend/source/tokeninfo.cpp deleted file mode 100644 index 1535eb2cc2..0000000000 --- a/src/tools/clangbackend/source/tokeninfo.cpp +++ /dev/null @@ -1,799 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangstring.h" -#include "cursor.h" -#include "token.h" -#include "tokeninfo.h" -#include "sourcelocation.h" -#include "sourcerange.h" -#include "sourcerangecontainer.h" - -#include <array> - -namespace ClangBackEnd { - -TokenInfo::TokenInfo(const Cursor &cursor, - const Token *token, - std::vector<CXSourceRange> ¤tOutputArgumentRanges) - : m_originalCursor(cursor), - m_token(token), - m_currentOutputArgumentRanges(¤tOutputArgumentRanges) -{ - const SourceRange sourceRange = token->extent(); - const auto start = sourceRange.start(); - const auto end = sourceRange.end(); - - m_line = start.line(); - m_column = start.column(); - m_offset = start.offset(); - m_length = token->spelling().operator Utf8String().toString().size(); - if (m_length == 0) - m_length = end.offset() - start.offset(); // Just for safety. -} - -bool TokenInfo::hasInvalidMainType() const -{ - return m_types.mainHighlightingType == HighlightingType::Invalid; -} - -bool TokenInfo::hasMainType(HighlightingType type) const -{ - return m_types.mainHighlightingType == type; -} - -unsigned TokenInfo::mixinSize() const { - return m_types.mixinHighlightingTypes.size(); -} - -bool TokenInfo::hasMixinType(HighlightingType type) const -{ - auto found = std::find(m_types.mixinHighlightingTypes.begin(), - m_types.mixinHighlightingTypes.end(), - type); - - return found != m_types.mixinHighlightingTypes.end(); -} - -bool TokenInfo::hasMixinTypeAt(uint position, HighlightingType type) const -{ - return m_types.mixinHighlightingTypes.size() > position && - m_types.mixinHighlightingTypes.at(position) == type; -} - -bool TokenInfo::hasOnlyType(HighlightingType type) const -{ - return m_types.mixinHighlightingTypes.size() == 0 && hasMainType(type); -} - -bool TokenInfo::hasFunctionArguments() const -{ - return m_originalCursor.argumentCount() > 0; -} - -TokenInfo::operator TokenInfoContainer() const -{ - return TokenInfoContainer(m_line, m_column, m_length, m_types); -} - -static bool isFinalFunction(const Cursor &cursor) -{ - auto referencedCursor = cursor.referenced(); - if (referencedCursor.hasFinalFunctionAttribute()) - return true; - else - return false; -} - -static bool isFunctionInFinalClass(const Cursor &cursor) -{ - auto functionBase = cursor.functionBaseDeclaration(); - if (functionBase.isValid() && functionBase.hasFinalClassAttribute()) - return true; - - return false; -} - -void TokenInfo::memberReferenceKind(const Cursor &cursor) -{ - if (cursor.isDynamicCall()) { - if (isFinalFunction(cursor) || isFunctionInFinalClass(cursor)) - m_types.mainHighlightingType = HighlightingType::Function; - else - m_types.mainHighlightingType = HighlightingType::VirtualFunction; - } else { - identifierKind(cursor.referenced(), Recursion::RecursivePass); - } -} - -void TokenInfo::overloadedDeclRefKind(const Cursor &cursor) -{ - m_types.mainHighlightingType = HighlightingType::Function; - - // CLANG-UPGRADE-CHECK: Workaround still needed? - // Workaround https://bugs.llvm.org//show_bug.cgi?id=33256 - SomeType in - // "using N::SomeType" is mistakenly considered as a CXCursor_OverloadedDeclRef. - if (cursor.overloadedDeclarationsCount() >= 1 - && cursor.overloadedDeclaration(0).kind() != CXCursor_FunctionDecl - && cursor.overloadedDeclaration(0).kind() != CXCursor_FunctionTemplate) { - m_types.mainHighlightingType = HighlightingType::Type; - } -} - -void TokenInfo::variableKind(const Cursor &cursor) -{ - if (cursor.isParameter()) - m_types.mainHighlightingType = HighlightingType::Parameter; - else if (cursor.isLocalVariable()) - m_types.mainHighlightingType = HighlightingType::LocalVariable; - else - m_types.mainHighlightingType = HighlightingType::GlobalVariable; - - if (isOutputArgument()) - m_types.mixinHighlightingTypes.push_back(HighlightingType::OutputArgument); -} - -void TokenInfo::fieldKind(const Cursor &cursor) -{ - m_types.mainHighlightingType = HighlightingType::Field; - - const CXCursorKind kind = cursor.kind(); - switch (kind) { - default: - m_types.mainHighlightingType = HighlightingType::Invalid; - return; - case CXCursor_ObjCPropertyDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::ObjectiveCProperty); - Q_FALLTHROUGH(); - case CXCursor_FieldDecl: - case CXCursor_MemberRef: - if (isOutputArgument()) - m_types.mixinHighlightingTypes.push_back(HighlightingType::OutputArgument); - return; - case CXCursor_ObjCClassMethodDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::ObjectiveCMethod); - return; - case CXCursor_ObjCIvarDecl: - case CXCursor_ObjCInstanceMethodDecl: - case CXCursor_ObjCSynthesizeDecl: - case CXCursor_ObjCDynamicDecl: - return; - } - -} - -bool TokenInfo::isDefinition() const -{ - return m_originalCursor.isDefinition(); -} - -bool TokenInfo::isVirtualMethodDeclarationOrDefinition(const Cursor &cursor) const -{ - return cursor.isVirtualMethod() - && (m_originalCursor.isDeclaration() || m_originalCursor.isDefinition()); -} - -static bool isNotFinalFunction(const Cursor &cursor) -{ - return !cursor.hasFinalFunctionAttribute(); -} - -bool TokenInfo::isRealDynamicCall(const Cursor &cursor) const -{ - return m_originalCursor.isDynamicCall() && isNotFinalFunction(cursor); -} - -void TokenInfo::addExtraTypeIfFirstPass(HighlightingType type, - Recursion recursion) -{ - if (recursion == Recursion::FirstPass) - m_types.mixinHighlightingTypes.push_back(type); -} - -bool TokenInfo::isArgumentInCurrentOutputArgumentLocations() const -{ - auto originalSourceLocation = m_originalCursor.cxSourceLocation(); - - const auto isNotSameOutputArgument = [&] (const CXSourceRange ¤tSourceRange) { - return originalSourceLocation.int_data >= currentSourceRange.begin_int_data - && originalSourceLocation.int_data <= currentSourceRange.end_int_data; - }; - - auto found = std::find_if(m_currentOutputArgumentRanges->begin(), - m_currentOutputArgumentRanges->end(), - isNotSameOutputArgument); - - bool isOutputArgument = found != m_currentOutputArgumentRanges->end(); - - return isOutputArgument; -} - -// For reasons I don't fully understand, the cursors from clang_annotateTokens() are sometimes -// not the actual cursor for the respective token, but the one for a construct higher up -// in the syntax tree. This is often not what we want (e.g. QTCREATORBUG-21522, QTCREATORBUG-21534), -// so in such cases we re-retrieve the cursor for the token via clang_getCursor(). -Cursor TokenInfo::realCursor(const Cursor &cursor) -{ - // Magic Qt stuff. - if (cursor.kind() == CXCursor_InvalidFile && invalidFileKind() != QtMacroPart::None) - return cursor; - - const SourceLocation tokenLoc = m_token->location(); - const SourceLocation cursorLoc = cursor.sourceLocation(); - if (tokenLoc == cursorLoc) - return cursor; - - // Note: clang_getTokenLocation() does not work. - const CXFile cxFile = clang_getFile(m_token->tu(), tokenLoc.filePath().toByteArray()); - const CXSourceLocation cxLoc = clang_getLocation(m_token->tu(), cxFile, tokenLoc.line(), - tokenLoc.column()); - return clang_getCursor(m_token->tu(), cxLoc); -} - -bool TokenInfo::isOutputArgument() const -{ - if (m_currentOutputArgumentRanges->empty()) - return false; - - return isArgumentInCurrentOutputArgumentLocations(); -} - -void TokenInfo::collectOutputArguments(const Cursor &cursor) -{ - cursor.collectOutputArgumentRangesTo(*m_currentOutputArgumentRanges); - filterOutPreviousOutputArguments(); -} - -static uint getEnd(CXSourceRange cxSourceRange) -{ - CXSourceLocation startSourceLocation = clang_getRangeEnd(cxSourceRange); - - uint endOffset; - - clang_getFileLocation(startSourceLocation, nullptr, nullptr, nullptr, &endOffset); - - return endOffset; -} - -void TokenInfo::filterOutPreviousOutputArguments() -{ - auto isAfterLocation = [this] (CXSourceRange outputRange) { - return getEnd(outputRange) > m_offset; - }; - - auto precedingBegin = std::partition(m_currentOutputArgumentRanges->begin(), - m_currentOutputArgumentRanges->end(), - isAfterLocation); - - m_currentOutputArgumentRanges->erase(precedingBegin, m_currentOutputArgumentRanges->end()); -} - -void TokenInfo::functionKind(const Cursor &cursor, Recursion recursion) -{ - if (isRealDynamicCall(cursor) || isVirtualMethodDeclarationOrDefinition(cursor)) - m_types.mainHighlightingType = HighlightingType::VirtualFunction; - else - m_types.mainHighlightingType = HighlightingType::Function; - - if (isOutputArgument()) - m_types.mixinHighlightingTypes.push_back(HighlightingType::OutputArgument); - - addExtraTypeIfFirstPass(HighlightingType::Declaration, recursion); - - if (isDefinition()) - addExtraTypeIfFirstPass(HighlightingType::FunctionDefinition, recursion); -} - -void TokenInfo::referencedTypeKind(const Cursor &cursor) -{ - typeKind(cursor.referenced()); -} - -void TokenInfo::typeKind(const Cursor &cursor) -{ - m_types.mainHighlightingType = HighlightingType::Type; - const CXCursorKind kind = cursor.kind(); - switch (kind) { - default: - m_types.mainHighlightingType = HighlightingType::Invalid; - return; - case CXCursor_TemplateRef: - case CXCursor_NamespaceRef: - case CXCursor_TypeRef: - referencedTypeKind(cursor); - return; - case CXCursor_ClassTemplate: - case CXCursor_ClassTemplatePartialSpecialization: - case CXCursor_ClassDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::Class); - return; - case CXCursor_UnionDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::Union); - return; - case CXCursor_StructDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::Struct); - return; - case CXCursor_EnumDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::Enum); - return; - case CXCursor_NamespaceAlias: - case CXCursor_Namespace: - m_types.mixinHighlightingTypes.push_back(HighlightingType::Namespace); - return; - case CXCursor_TypeAliasDecl: - case CXCursor_TypeAliasTemplateDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::TypeAlias); - return; - case CXCursor_TypedefDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::Typedef); - return; - case CXCursor_ObjCClassRef: - m_types.mixinHighlightingTypes.push_back(HighlightingType::ObjectiveCClass); - return; - case CXCursor_ObjCProtocolDecl: - case CXCursor_ObjCProtocolRef: - m_types.mixinHighlightingTypes.push_back(HighlightingType::ObjectiveCProtocol); - return; - case CXCursor_ObjCInterfaceDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::ObjectiveCInterface); - return; - case CXCursor_ObjCImplementationDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::ObjectiveCImplementation); - return; - case CXCursor_ObjCCategoryDecl: - case CXCursor_ObjCCategoryImplDecl: - m_types.mixinHighlightingTypes.push_back(HighlightingType::ObjectiveCCategory); - return; - case CXCursor_TemplateTypeParameter: - m_types.mixinHighlightingTypes.push_back(HighlightingType::TemplateTypeParameter); - return; - case CXCursor_TemplateTemplateParameter: - m_types.mixinHighlightingTypes.push_back(HighlightingType::TemplateTemplateParameter); - return; - case CXCursor_ObjCSuperClassRef: - case CXCursor_CXXStaticCastExpr: - case CXCursor_CXXReinterpretCastExpr: - break; - } -} - -void TokenInfo::identifierKind(const Cursor &cursor, Recursion recursion) -{ - if (cursor.isInvalidDeclaration()) - return; - - if (recursion == Recursion::FirstPass - && cursor.kind() != CXCursor_NotImplemented - && cursor.kind() != CXCursor_PreprocessingDirective) { - const Cursor c = realCursor(cursor); - if (!clang_isInvalid(c.kind()) && c != cursor) { - identifierKind(c, Recursion::FirstPass); - return; - } - } - - const CXCursorKind kind = cursor.kind(); - switch (kind) { - case CXCursor_Destructor: - case CXCursor_Constructor: - case CXCursor_FunctionDecl: - case CXCursor_FunctionTemplate: - case CXCursor_CallExpr: - case CXCursor_CXXMethod: - functionKind(cursor, recursion); - break; - case CXCursor_NonTypeTemplateParameter: - m_types.mainHighlightingType = HighlightingType::LocalVariable; - break; - case CXCursor_ParmDecl: - case CXCursor_VarDecl: - case CXCursor_VariableRef: - case CXCursor_UnexposedDecl: // structured bindings; see https://reviews.llvm.org/D78213 - variableKind(cursor.referenced()); - break; - case CXCursor_DeclRefExpr: - identifierKind(cursor.referenced(), Recursion::RecursivePass); - break; - case CXCursor_MemberRefExpr: - memberReferenceKind(cursor); - break; - case CXCursor_FieldDecl: - case CXCursor_MemberRef: - case CXCursor_ObjCPropertyDecl: - case CXCursor_ObjCIvarDecl: - case CXCursor_ObjCClassMethodDecl: - case CXCursor_ObjCInstanceMethodDecl: - case CXCursor_ObjCSynthesizeDecl: - case CXCursor_ObjCDynamicDecl: - fieldKind(cursor); - break; - case CXCursor_TemplateRef: - case CXCursor_NamespaceRef: - case CXCursor_TypeRef: - referencedTypeKind(cursor); - break; - case CXCursor_ClassDecl: - case CXCursor_ClassTemplate: - case CXCursor_ClassTemplatePartialSpecialization: - case CXCursor_UnionDecl: - case CXCursor_StructDecl: - case CXCursor_EnumDecl: - case CXCursor_Namespace: - m_types.mixinHighlightingTypes.push_back(HighlightingType::Declaration); - Q_FALLTHROUGH(); - case CXCursor_TemplateTypeParameter: - case CXCursor_TemplateTemplateParameter: - case CXCursor_NamespaceAlias: - case CXCursor_TypeAliasDecl: - case CXCursor_TypedefDecl: - case CXCursor_CXXStaticCastExpr: - case CXCursor_CXXReinterpretCastExpr: - case CXCursor_ObjCCategoryDecl: - case CXCursor_ObjCCategoryImplDecl: - case CXCursor_ObjCImplementationDecl: - case CXCursor_ObjCInterfaceDecl: - case CXCursor_ObjCProtocolDecl: - case CXCursor_ObjCProtocolRef: - case CXCursor_ObjCClassRef: - case CXCursor_ObjCSuperClassRef: - typeKind(cursor); - break; - case CXCursor_OverloadedDeclRef: - overloadedDeclRefKind(cursor); - break; - case CXCursor_EnumConstantDecl: - m_types.mainHighlightingType = HighlightingType::Enumeration; - break; - case CXCursor_PreprocessingDirective: - m_types.mainHighlightingType = HighlightingType::Preprocessor; - break; - case CXCursor_MacroExpansion: - m_types.mainHighlightingType = HighlightingType::PreprocessorExpansion; - break; - case CXCursor_MacroDefinition: - m_types.mainHighlightingType = HighlightingType::PreprocessorDefinition; - break; - case CXCursor_InclusionDirective: - // Included files are sometimes reported as strings and sometimes as - // include directives, depending on various circumstances. - m_types.mainHighlightingType = m_token->spelling() == "include" - ? HighlightingType::Preprocessor : HighlightingType::StringLiteral; - break; - case CXCursor_LabelRef: - case CXCursor_LabelStmt: - m_types.mainHighlightingType = HighlightingType::Label; - break; - default: - break; - } -} - -static HighlightingType literalKind(const Cursor &cursor) -{ - switch (cursor.kind()) { - case CXCursor_CharacterLiteral: - case CXCursor_StringLiteral: - case CXCursor_InclusionDirective: - case CXCursor_ObjCStringLiteral: - return HighlightingType::StringLiteral; - case CXCursor_IntegerLiteral: - case CXCursor_ImaginaryLiteral: - case CXCursor_FloatingLiteral: - return HighlightingType::NumberLiteral; - default: - return HighlightingType::Invalid; - } - - Q_UNREACHABLE(); -} - -static bool isTokenPartOfOperator(const Cursor &declarationCursor, const Token &token) -{ - Q_ASSERT(declarationCursor.isDeclaration()); - const CXTranslationUnit cxTranslationUnit = declarationCursor.cxTranslationUnit(); - const ClangString tokenName = token.spelling(); - if (tokenName == "operator") - return true; - - if (tokenName == "(") { - // Valid operator declarations have at least one token after '(' so - // it's safe to proceed to token + 1 without extra checks. - const ClangString nextToken = clang_getTokenSpelling(cxTranslationUnit, *(token.cx() + 1)); - if (nextToken != ")") { - // Argument lists' parentheses are not operator tokens. - // This '('-token opens a (non-empty) argument list. - return false; - } - } - - // It's safe to evaluate the preceding token because we will at least have - // the 'operator'-keyword's token to the left. - CXToken *prevToken = token.cx() - 1; - if (clang_getTokenKind(*prevToken) == CXToken_Punctuation) { - if (tokenName == "(") { - // In an operator declaration, when a '(' follows another punctuation - // then this '(' opens an argument list. Ex: operator*()|operator()(). - return false; - } - - // This token is preceded by another punctuation token so this token - // could be the second token of a two-tokened operator such as - // operator+=|-=|*=|/=|<<|==|<=|++ or the third token of operator - // new[]|delete[]. We decrement one more time to hit one of the keywords: - // "operator" / "delete" / "new". - --prevToken; - } - - const ClangString precedingKeyword = - clang_getTokenSpelling(cxTranslationUnit, *prevToken); - - return precedingKeyword == "operator" || - precedingKeyword == "new" || - precedingKeyword == "delete"; -} - -void TokenInfo::overloadedOperatorKind() -{ - bool inOperatorDeclaration = m_originalCursor.isDeclaration(); - Cursor declarationCursor = - inOperatorDeclaration ? m_originalCursor : - m_originalCursor.referenced(); - if (!declarationCursor.displayName().startsWith("operator")) - return; - - if (inOperatorDeclaration && !isTokenPartOfOperator(declarationCursor, *m_token)) - return; - - m_types.mixinHighlightingTypes.push_back(HighlightingType::Operator); - m_types.mixinHighlightingTypes.push_back(HighlightingType::OverloadedOperator); -} - -void TokenInfo::punctuationOrOperatorKind() -{ - m_types.mainHighlightingType = HighlightingType::Punctuation; - auto kind = m_originalCursor.kind(); - switch (kind) { - case CXCursor_CallExpr: - collectOutputArguments(m_originalCursor); - Q_FALLTHROUGH(); - case CXCursor_FunctionDecl: - case CXCursor_CXXMethod: - case CXCursor_DeclRefExpr: - // TODO(QTCREATORBUG-19948): Mark calls to overloaded new and delete. - // Today we can't because libclang sets these cursors' spelling to "". - // case CXCursor_CXXNewExpr: - // case CXCursor_CXXDeleteExpr: - overloadedOperatorKind(); - break; - case CXCursor_UnaryOperator: - case CXCursor_BinaryOperator: - case CXCursor_CompoundAssignOperator: - case CXCursor_ConditionalOperator: - m_types.mixinHighlightingTypes.push_back(HighlightingType::Operator); - if (kind == CXCursor_ConditionalOperator) { - if (m_token->spelling() == "?") - m_types.mixinHighlightingTypes.push_back(HighlightingType::TernaryIf); - else - m_types.mixinHighlightingTypes.push_back(HighlightingType::TernaryElse); - } - break; - default: - break; - } - - if (m_types.mainHighlightingType == HighlightingType::Punctuation - && m_types.mixinHighlightingTypes.empty() - && kind != CXCursor_OverloadedDeclRef - && kind != CXCursor_InclusionDirective - && kind != CXCursor_PreprocessingDirective - && kind != CXCursor_MacroDefinition - && kind != CXCursor_DeclStmt - && kind != CXCursor_CompoundStmt - && kind != CXCursor_FirstInvalid) { - const ClangString spelling = m_token->spelling(); - if (spelling == "<") - m_types.mixinHighlightingTypes.push_back(HighlightingType::AngleBracketOpen); - else if (spelling == ">") - m_types.mixinHighlightingTypes.push_back(HighlightingType::AngleBracketClose); - else if (spelling == ">>") - m_types.mixinHighlightingTypes.push_back(HighlightingType::DoubleAngleBracketClose); - } - - if (isOutputArgument()) - m_types.mixinHighlightingTypes.push_back(HighlightingType::OutputArgument); -} - -static bool isFirstTokenOfCursor(const Cursor &cursor, const Token &token) -{ - return cursor.sourceLocation() == token.location(); -} - -static bool isLastTokenOfCursor(const Cursor &cursor, const Token &token) -{ - return cursor.sourceRange().end() == token.location(); -} - -static bool isValidMacroToken(const Cursor &cursor, const Token &token) -{ - // Proper macro token has at least '(' and ')' around it. - return !isFirstTokenOfCursor(cursor, token) && !isLastTokenOfCursor(cursor, token); -} - -TokenInfo::QtMacroPart TokenInfo::propertyPart(const Token &token) -{ - static constexpr const char *propertyKeywords[] - = {"READ", "WRITE", "MEMBER", "RESET", "NOTIFY", "REVISION", "DESIGNABLE", - "SCRIPTABLE", "STORED", "USER", "CONSTANT", "FINAL" - }; - - if (std::find(std::begin(propertyKeywords), std::end(propertyKeywords), token.spelling()) - != std::end(propertyKeywords)) { - return QtMacroPart::Keyword; - } - - const ClangString nextToken = clang_getTokenSpelling(token.tu(), *(token.cx() + 1)); - const ClangString previousToken = clang_getTokenSpelling(token.tu(), *(token.cx() - 1)); - if (std::find(std::begin(propertyKeywords), std::end(propertyKeywords), nextToken) - != std::end(propertyKeywords)) { - if (std::find(std::begin(propertyKeywords), std::end(propertyKeywords), previousToken) - == std::end(propertyKeywords)) { - return QtMacroPart::Property; - } - - return QtMacroPart::FunctionOrPrimitiveType; - } - - if (std::find(std::begin(propertyKeywords), std::end(propertyKeywords), previousToken) - != std::end(propertyKeywords)) { - return QtMacroPart::FunctionOrPrimitiveType; - } - return QtMacroPart::Type; -} - -TokenInfo::QtMacroPart TokenInfo::signalSlotPart(CXTranslationUnit cxTranslationUnit, - CXToken *token, bool signal) -{ - // We are inside macro so current token has at least '(' and macro name before it. - const ClangString prevToken = clang_getTokenSpelling(cxTranslationUnit, *(token - 2)); - if (signal) - return (prevToken == "SIGNAL") ? QtMacroPart::SignalFunction : QtMacroPart::SignalType; - return (prevToken == "SLOT") ? QtMacroPart::SlotFunction : QtMacroPart::SlotType; -} - -TokenInfo::QtMacroPart TokenInfo::qtMacroPart(const Token &token) -{ - const SourceLocation location = token.location(); - - // If current token is inside macro then the cursor from token's position will be - // the whole macro cursor. - Cursor possibleQtMacroCursor = clang_getCursor(token.tu(), location.cx()); - if (!isValidMacroToken(possibleQtMacroCursor, token)) - return QtMacroPart::None; - - ClangString spelling = possibleQtMacroCursor.spelling(); - if (spelling == "Q_PROPERTY") - return propertyPart(token); - - if (spelling == "SIGNAL") - return signalSlotPart(token.tu(), token.cx(), true); - if (spelling == "SLOT") - return signalSlotPart(token.tu(), token.cx(), false); - return QtMacroPart::None; -} - -TokenInfo::QtMacroPart TokenInfo::invalidFileKind() -{ - const QtMacroPart macroPart = qtMacroPart(*m_token); - - switch (macroPart) { - case QtMacroPart::None: - case QtMacroPart::Keyword: - m_types.mainHighlightingType = HighlightingType::Invalid; - break; - case QtMacroPart::SignalFunction: - case QtMacroPart::SlotFunction: - m_types.mainHighlightingType = HighlightingType::Function; - break; - case QtMacroPart::SignalType: - case QtMacroPart::SlotType: - m_types.mainHighlightingType = HighlightingType::Type; - break; - case QtMacroPart::Property: - m_types.mainHighlightingType = HighlightingType::QtProperty; - break; - case QtMacroPart::Type: - m_types.mainHighlightingType = HighlightingType::Type; - break; - case QtMacroPart::FunctionOrPrimitiveType: - m_types.mainHighlightingType = HighlightingType::Function; - break; - } - - return macroPart; -} - -void TokenInfo::keywordKind() -{ - switch (m_originalCursor.kind()) { - case CXCursor_PreprocessingDirective: - m_types.mainHighlightingType = HighlightingType::Preprocessor; - return; - case CXCursor_InclusionDirective: - m_types.mainHighlightingType = HighlightingType::StringLiteral; - return; - default: - break; - } - - const ClangString spelling = m_token->spelling(); - if (spelling == "bool" - || spelling == "char" - || spelling == "char16_t" - || spelling == "char32_t" - || spelling == "double" - || spelling == "float" - || spelling == "int" - || spelling == "long" - || spelling == "short" - || spelling == "signed" - || spelling == "unsigned" - || spelling == "void" - || spelling == "wchar_t") { - m_types.mainHighlightingType = HighlightingType::PrimitiveType; - return; - } - - m_types.mainHighlightingType = HighlightingType::Keyword; - - if (spelling == "new" || spelling == "delete" || spelling == "operator") - overloadedOperatorKind(); -} - -void TokenInfo::evaluate() -{ - auto cxTokenKind = m_token->kind(); - - m_types = HighlightingTypes(); - - switch (cxTokenKind) { - case CXToken_Keyword: - keywordKind(); - break; - case CXToken_Punctuation: - punctuationOrOperatorKind(); - break; - case CXToken_Identifier: - identifierKind(m_originalCursor, Recursion::FirstPass); - break; - case CXToken_Comment: - m_types.mainHighlightingType = HighlightingType::Comment; - break; - case CXToken_Literal: - m_types.mainHighlightingType = literalKind(m_originalCursor); - break; - } -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/tokeninfo.h b/src/tools/clangbackend/source/tokeninfo.h deleted file mode 100644 index 8aa868e05d..0000000000 --- a/src/tools/clangbackend/source/tokeninfo.h +++ /dev/null @@ -1,145 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangsupport_global.h" -#include "cursor.h" - -#include <clangsupport/tokeninfocontainer.h> - -#include <clangsupport/utf8string.h> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -class Cursor; -class Token; - -class TokenInfo -{ - friend bool operator==(const TokenInfo &first, const TokenInfo &second); - template<class T> friend class TokenProcessor; -public: - TokenInfo() = default; - TokenInfo(const Cursor &cursor, - const Token *token, - std::vector<CXSourceRange> &m_currentOutputArgumentRanges); - virtual ~TokenInfo() = default; - - virtual void evaluate(); - - bool hasInvalidMainType() const; - bool hasMainType(HighlightingType type) const; - unsigned mixinSize() const; - bool hasMixinType(HighlightingType type) const; - bool hasMixinTypeAt(uint, HighlightingType type) const; - bool hasOnlyType(HighlightingType type) const; - bool hasFunctionArguments() const; - - virtual operator TokenInfoContainer() const; - - const HighlightingTypes &types() const - { - return m_types; - } - - uint line () const - { - return m_line; - } - - uint column() const - { - return m_column; - } - - uint length() const - { - return m_length; - } - -protected: - enum class Recursion { - FirstPass, - RecursivePass - }; - - virtual void identifierKind(const Cursor &cursor, Recursion recursion); - virtual void referencedTypeKind(const Cursor &cursor); - virtual void overloadedDeclRefKind(const Cursor &cursor); - virtual void variableKind(const Cursor &cursor); - virtual void fieldKind(const Cursor &cursor); - virtual void functionKind(const Cursor &cursor, Recursion recursion); - virtual void memberReferenceKind(const Cursor &cursor); - virtual void typeKind(const Cursor &cursor); - virtual void keywordKind(); - virtual void overloadedOperatorKind(); - virtual void punctuationOrOperatorKind(); - - enum class QtMacroPart { - None, SignalFunction, SignalType, SlotFunction, SlotType, Type, Property, Keyword, - FunctionOrPrimitiveType - }; - virtual QtMacroPart invalidFileKind(); - - Cursor m_originalCursor; - const Token *m_token; - HighlightingTypes m_types; - -private: - bool isVirtualMethodDeclarationOrDefinition(const Cursor &cursor) const; - bool isDefinition() const; - bool isRealDynamicCall(const Cursor &cursor) const; - void addExtraTypeIfFirstPass(HighlightingType type, Recursion recursion); - bool isOutputArgument() const; - void collectOutputArguments(const Cursor &cursor); - void filterOutPreviousOutputArguments(); - bool isArgumentInCurrentOutputArgumentLocations() const; - Cursor realCursor(const Cursor &cursor); - - static QtMacroPart propertyPart(const Token &token); - static QtMacroPart signalSlotPart(CXTranslationUnit cxTranslationUnit, CXToken *token, - bool signal); - static QtMacroPart qtMacroPart(const Token &token); - - std::vector<CXSourceRange> *m_currentOutputArgumentRanges = nullptr; - uint m_line = 0; - uint m_column = 0; - uint m_length = 0; - uint m_offset = 0; -}; - - -inline bool operator==(const TokenInfo &first, const TokenInfo &second) -{ - return first.m_line == second.m_line - && first.m_column == second.m_column - && first.m_length == second.m_length - && first.m_types == second.m_types; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/tokenprocessor.h b/src/tools/clangbackend/source/tokenprocessor.h deleted file mode 100644 index a0e42bffcf..0000000000 --- a/src/tools/clangbackend/source/tokenprocessor.h +++ /dev/null @@ -1,165 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "fulltokeninfo.h" -#include "sourcerange.h" -#include "token.h" -#include "tokenprocessoriterator.h" -#include "tokeninfocontainer.h" - -#include <utils/algorithm.h> - -#include <clang-c/Index.h> - -#include <QVector> - -#include <vector> - -namespace ClangBackEnd { - -template<class T> -class TokenProcessor -{ - static_assert (std::is_base_of<TokenInfo, T>::value, - "Use TokenProcessor only with classes derived from TokenInfo"); - -public: - using const_iterator = TokenProcessorIterator<T>; - using value_type = T; - -public: - TokenProcessor() = default; - TokenProcessor(const SourceRange &range) - : tokens(range) - , cursors(tokens.annotate()) - { - } - - bool isEmpty() const - { - return cursors.empty(); - } - bool isNull() const - { - return !tokens.size(); - } - size_t size() const - { - return cursors.size(); - } - - const_iterator begin() const - { - return const_iterator(cursors.cbegin(), - tokens.cbegin(), - currentOutputArgumentRanges); - } - - const_iterator end() const - { - return const_iterator(cursors.cend(), - tokens.cend(), - currentOutputArgumentRanges); - } - - - T operator[](size_t index) const - { - T tokenInfo(cursors[index], &tokens[index], currentOutputArgumentRanges); - tokenInfo.evaluate(); - return tokenInfo; - } - - QVector<TokenInfoContainer> toTokenInfoContainers() const - { - return toTokens<TokenInfoContainer>(); - } - - bool currentOutputArgumentRangesAreEmpty() const - { - return currentOutputArgumentRanges.empty(); - } - -private: - template<class TC> - QVector<TC> toTokens() const - { - QVector<TC> tokenInfos; - tokenInfos.reserve(int(size())); - - const auto isValidTokenInfo = [](const T &tokenInfo) { - return !tokenInfo.hasInvalidMainType() - && !tokenInfo.hasMainType(HighlightingType::NumberLiteral) - && !tokenInfo.hasMainType(HighlightingType::Comment); - }; - - for (size_t index = 0; index < cursors.size(); ++index) { - T tokenInfo = (*this)[index]; - if (isValidTokenInfo(tokenInfo)) - tokenInfos.push_back(tokenInfo); - } - - return tokenInfos; - } - - mutable std::vector<CXSourceRange> currentOutputArgumentRanges; - Tokens tokens; - std::vector<Cursor> cursors; -}; - -template <> -inline -QVector<TokenInfoContainer> TokenProcessor<FullTokenInfo>::toTokenInfoContainers() const -{ - QVector<FullTokenInfo> tokenInfos = toTokens<FullTokenInfo>(); - - return Utils::transform(tokenInfos, - [&tokenInfos](FullTokenInfo &tokenInfo) -> TokenInfoContainer { - if (!tokenInfo.m_extraInfo.declaration - || tokenInfo.hasMainType(HighlightingType::LocalVariable)) { - return tokenInfo; - } - - const int index = tokenInfos.indexOf(tokenInfo); - const SourceLocationContainer &tokenStart = tokenInfo.m_extraInfo.cursorRange.start; - for (auto it = tokenInfos.rend() - index; it != tokenInfos.rend(); ++it) { - if (it->m_extraInfo.declaration && !it->hasMainType(HighlightingType::LocalVariable) - && it->m_originalCursor != tokenInfo.m_originalCursor - && it->m_extraInfo.cursorRange.contains(tokenStart)) { - if (tokenInfo.m_originalCursor.lexicalParent() != it->m_originalCursor - && !tokenInfo.hasMainType(HighlightingType::QtProperty)) { - continue; - } - tokenInfo.m_extraInfo.lexicalParentIndex = std::distance(it, tokenInfos.rend()) - 1; - break; - } - } - return tokenInfo; - }); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/tokenprocessoriterator.h b/src/tools/clangbackend/source/tokenprocessoriterator.h deleted file mode 100644 index 08bdbc1546..0000000000 --- a/src/tools/clangbackend/source/tokenprocessoriterator.h +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "tokeninfo.h" - -#include <iterator> -#include <vector> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -class DiagnosticSet; -class Diagnostic; - -template<class T> -class TokenProcessorIterator -{ -public: - using iterator_category = std::forward_iterator_tag; - using value_type = TokenInfo; - using difference_type = int; - using pointer = TokenInfo *; - using reference = TokenInfo &; - - TokenProcessorIterator(std::vector<Cursor>::const_iterator cursorIterator, - std::vector<Token>::const_iterator tokenIterator, - std::vector<CXSourceRange> ¤tOutputArgumentRanges) - : cursorIterator(cursorIterator), - tokenIterator(tokenIterator), - currentOutputArgumentRanges(currentOutputArgumentRanges) - {} - - TokenProcessorIterator& operator++() - { - ++cursorIterator; - ++tokenIterator; - - return *this; - } - - TokenProcessorIterator operator++(int) - { - return TokenProcessorIterator(cursorIterator++, - tokenIterator++, - currentOutputArgumentRanges); - } - - bool operator==(TokenProcessorIterator other) const - { - return cursorIterator == other.cursorIterator; - } - - bool operator!=(TokenProcessorIterator other) const - { - return cursorIterator != other.cursorIterator; - } - - T operator*() - { - T tokenInfo(*cursorIterator, &(*tokenIterator), currentOutputArgumentRanges); - tokenInfo.evaluate(); - return tokenInfo; - } - -private: - std::vector<Cursor>::const_iterator cursorIterator; - std::vector<Token>::const_iterator tokenIterator; - std::vector<CXSourceRange> ¤tOutputArgumentRanges; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/unsavedfile.cpp b/src/tools/clangbackend/source/unsavedfile.cpp deleted file mode 100644 index df667a3630..0000000000 --- a/src/tools/clangbackend/source/unsavedfile.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "unsavedfile.h" - -#include "clangfilepath.h" -#include "utf8positionfromlinecolumn.h" - -#include <ostream> - -#include <utils/qtcassert.h> - -namespace ClangBackEnd { - -UnsavedFile::UnsavedFile() -{ -} - -UnsavedFile::UnsavedFile(const Utf8String &filePath, - const Utf8String &fileContent) - : m_filePath(filePath) - , m_nativeFilePath(FilePath::toNativeSeparators(filePath)) - , m_fileContent(fileContent) -{ -} - -Utf8String UnsavedFile::nativeFilePath() const -{ - return m_nativeFilePath; -} - -Utf8String UnsavedFile::filePath() const -{ - return m_filePath; -} - -Utf8String UnsavedFile::fileContent() const -{ - return m_fileContent; -} - -uint UnsavedFile::toUtf8Position(int line, int column, bool *ok) const -{ - Utf8PositionFromLineColumn converter(m_fileContent.constData()); - if (converter.find(line, column)) { - *ok = true; - return converter.position(); - } - - *ok = false; - return 0; -} - -bool UnsavedFile::hasCharacterAt(int line, int column, char character) const -{ - bool positionIsOk = false; - const uint utf8Position = toUtf8Position(line, column, &positionIsOk); - - return positionIsOk && hasCharacterAt(utf8Position, character); -} - -Utf8String UnsavedFile::lineRange(int fromLine, int toLine) const -{ - if (fromLine > toLine) - return Utf8String(); - - // Find start of first line - bool ok = false; - const uint fromPosition = toUtf8Position(fromLine, 1, &ok); - QTC_ASSERT(ok, return Utf8String()); - - // Find end of last line - uint toPosition = toUtf8Position(toLine, 1, &ok); - QTC_ASSERT(ok, return Utf8String()); - const uint endPosition = uint(m_fileContent.byteSize()); - while (toPosition < endPosition && m_fileContent.constData()[toPosition] != '\n') - ++toPosition; - - return m_fileContent.mid(int(fromPosition), int(toPosition - fromPosition)); -} - -bool UnsavedFile::hasCharacterAt(uint position, char character) const -{ - if (position < uint(m_fileContent.byteSize())) - return m_fileContent.constData()[position] == character; - - return false; -} - -bool UnsavedFile::replaceAt(uint position, uint length, const Utf8String &replacement) -{ - if (position < uint(m_fileContent.byteSize())) { - m_fileContent.replace(int(position), int(length), replacement); - return true; - } - - return false; -} - -std::ostream &operator<<(std::ostream &os, const UnsavedFile &unsavedFile) -{ - os << "UnsavedFile(" - << unsavedFile.m_filePath << ", " - << unsavedFile.m_fileContent << ", " - << unsavedFile.m_fileContent << ")"; - - return os; -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/unsavedfile.h b/src/tools/clangbackend/source/unsavedfile.h deleted file mode 100644 index 58966dd9bb..0000000000 --- a/src/tools/clangbackend/source/unsavedfile.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "utf8string.h" - -namespace ClangBackEnd { - -using uint = unsigned int; - -class UnsavedFile -{ -public: - friend std::ostream &operator<<(std::ostream &os, const UnsavedFile &unsavedFile); - - UnsavedFile(); - UnsavedFile(const Utf8String &filePath, const Utf8String &fileContent); - - Utf8String filePath() const; - Utf8String nativeFilePath() const; - Utf8String fileContent() const; - - // 1-based line and column - uint toUtf8Position(int line, int column, bool *ok) const; - bool hasCharacterAt(int line, int column, char character) const; - Utf8String lineRange(int fromLine, int toLine) const; - - // 0-based position - bool hasCharacterAt(uint position, char character) const; - bool replaceAt(uint position, uint length, const Utf8String &replacement); - -private: - Utf8String m_filePath; - Utf8String m_nativeFilePath; - Utf8String m_fileContent; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/unsavedfiles.cpp b/src/tools/clangbackend/source/unsavedfiles.cpp deleted file mode 100644 index f436c660d0..0000000000 --- a/src/tools/clangbackend/source/unsavedfiles.cpp +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "unsavedfiles.h" - -#include "clangunsavedfilesshallowarguments.h" -#include "unsavedfile.h" - -#include <QSharedData> - -#include <algorithm> - -namespace ClangBackEnd { - -class UnsavedFilesData : public QSharedData -{ -public: - UnsavedFilesData(); - -public: - TimePoint lastChangeTimePoint; - QVector<UnsavedFile> unsavedFiles; -}; - -UnsavedFilesData::UnsavedFilesData() - : lastChangeTimePoint(Clock::now()) -{ -} - -UnsavedFiles::UnsavedFiles() - : d(new UnsavedFilesData) -{ -} - -UnsavedFiles::~UnsavedFiles() -{ -} - -UnsavedFiles::UnsavedFiles(const UnsavedFiles &other) - : d(other.d) -{ -} - -UnsavedFiles &UnsavedFiles::operator=(const UnsavedFiles &other) -{ - d = other.d; - return *this; -} - -void UnsavedFiles::createOrUpdate(const QVector<FileContainer> &fileContainers) -{ - for (const FileContainer &fileContainer : fileContainers) - updateUnsavedFileWithFileContainer(fileContainer); - - updateLastChangeTimePoint(); -} - -void UnsavedFiles::remove(const QVector<FileContainer> &fileContainers) -{ - for (const FileContainer &fileContainer : fileContainers) - removeUnsavedFile(fileContainer); - - updateLastChangeTimePoint(); -} - -UnsavedFile &UnsavedFiles::unsavedFile(const Utf8String &filePath) -{ - const auto isMatchingFile = [filePath] (const UnsavedFile &unsavedFile) { - return unsavedFile.filePath() == filePath; - }; - const auto unsavedFileIterator = std::find_if(d->unsavedFiles.begin(), - d->unsavedFiles.end(), - isMatchingFile); - - if (unsavedFileIterator != d->unsavedFiles.end()) - return *unsavedFileIterator; - - static UnsavedFile defaultUnsavedFile = UnsavedFile(Utf8String(), Utf8String()); - return defaultUnsavedFile; -} - -uint UnsavedFiles::count() const -{ - return uint(d->unsavedFiles.size()); -} - -const UnsavedFile &UnsavedFiles::at(int index) const -{ - return d->unsavedFiles.at(index); -} - -UnsavedFilesShallowArguments UnsavedFiles::shallowArguments() const -{ - return UnsavedFilesShallowArguments(*this); -} - -const TimePoint UnsavedFiles::lastChangeTimePoint() const -{ - return d->lastChangeTimePoint; -} - -void UnsavedFiles::updateUnsavedFileWithFileContainer(const FileContainer &fileContainer) -{ - if (fileContainer.hasUnsavedFileContent) - addOrUpdateUnsavedFile(fileContainer); - else - removeUnsavedFile(fileContainer); -} - -void UnsavedFiles::removeUnsavedFile(const FileContainer &fileContainer) -{ - const Utf8String &filePath = fileContainer.filePath; - auto removeBeginIterator = std::partition(d->unsavedFiles.begin(), - d->unsavedFiles.end(), - [filePath] (const UnsavedFile &unsavedFile) { return filePath != unsavedFile.filePath(); }); - - d->unsavedFiles.erase(removeBeginIterator, d->unsavedFiles.end()); -} - -void UnsavedFiles::addOrUpdateUnsavedFile(const FileContainer &fileContainer) -{ - const Utf8String &filePath = fileContainer.filePath; - const Utf8String &fileContent = fileContainer.unsavedFileContent; - auto isSameFile = [filePath] (const UnsavedFile &unsavedFile) { return filePath == unsavedFile.filePath(); }; - - auto unsavedFileIterator = std::find_if(d->unsavedFiles.begin(), d->unsavedFiles.end(), isSameFile); - if (unsavedFileIterator == d->unsavedFiles.end()) - d->unsavedFiles.append(UnsavedFile(filePath, fileContent)); - else - *unsavedFileIterator = UnsavedFile(filePath, fileContent); -} - -void UnsavedFiles::updateLastChangeTimePoint() -{ - d->lastChangeTimePoint = Clock::now(); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/unsavedfiles.h b/src/tools/clangbackend/source/unsavedfiles.h deleted file mode 100644 index eacab0bc34..0000000000 --- a/src/tools/clangbackend/source/unsavedfiles.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "clangclock.h" - -#include <filecontainer.h> - -#include <QSharedPointer> -#include <QVector> - -#include <clang-c/Index.h> - -namespace ClangBackEnd { - -class UnsavedFile; -class UnsavedFilesData; -class UnsavedFilesShallowArguments; - -class UnsavedFiles -{ -public: - UnsavedFiles(); - ~UnsavedFiles(); - - UnsavedFiles(const UnsavedFiles &other); - UnsavedFiles &operator=(const UnsavedFiles &other); - - void createOrUpdate(const QVector<FileContainer> &fileContainers); - void remove(const QVector<FileContainer> &fileContainers); - - uint count() const; - const UnsavedFile &at(int index) const; - - UnsavedFile &unsavedFile(const Utf8String &filePath); - - UnsavedFilesShallowArguments shallowArguments() const; - - const TimePoint lastChangeTimePoint() const; - -private: - void updateUnsavedFileWithFileContainer(const FileContainer &fileContainer); - void removeUnsavedFile(const FileContainer &fileContainer); - void addOrUpdateUnsavedFile(const FileContainer &fileContainer); - void updateLastChangeTimePoint(); - -private: - QSharedDataPointer<UnsavedFilesData> d; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/utf8positionfromlinecolumn.cpp b/src/tools/clangbackend/source/utf8positionfromlinecolumn.cpp deleted file mode 100644 index 36f5747a5b..0000000000 --- a/src/tools/clangbackend/source/utf8positionfromlinecolumn.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "utf8positionfromlinecolumn.h" - -#include <utils/textutils.h> - -#include <QtGlobal> - -namespace ClangBackEnd { - -Utf8PositionFromLineColumn::Utf8PositionFromLineColumn(const char *utf8Text) - : m_utf8Text(utf8Text) - , m_currentByte(utf8Text) -{ -} - -bool Utf8PositionFromLineColumn::find(int line, int column) -{ - if (!m_utf8Text || *m_utf8Text == '\0' || line == 0 || column == 0) - return false; - - return advanceToLine(line) - && advanceToColumn(column); -} - -uint Utf8PositionFromLineColumn::position() const -{ - return m_previousByte - m_utf8Text; -} - -bool Utf8PositionFromLineColumn::advanceToLine(int line) -{ - if (line == 1) - return true; - - int currentLine = 1; - do { - if (*m_currentByte == '\n' && ++currentLine == line) { - advanceCodePoint(); - return true; - } - } while (advanceCodePoint()); - - return false; -} - -bool Utf8PositionFromLineColumn::advanceToColumn(int column) -{ - while (column) { - if (advanceCodePoint(/*stopOnNewLine=*/ true)) - --column; - else - break; - } - - return column == 0; -} - -bool Utf8PositionFromLineColumn::advanceCodePoint(bool stopOnNewLine) -{ - if (Q_UNLIKELY(*m_currentByte == '\0') || (stopOnNewLine && *m_currentByte == '\n')) - return false; - - m_previousByte = m_currentByte; - return Utils::Text::utf8AdvanceCodePoint(m_currentByte); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/utf8positionfromlinecolumn.h b/src/tools/clangbackend/source/utf8positionfromlinecolumn.h deleted file mode 100644 index 22f5b7ff54..0000000000 --- a/src/tools/clangbackend/source/utf8positionfromlinecolumn.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -namespace ClangBackEnd { - -using uint = unsigned; - -class Utf8PositionFromLineColumn -{ -public: - Utf8PositionFromLineColumn(const char *utf8Text); - - // 1-based line and column - bool find(int line, int column); - - uint position() const; - -private: - bool advanceToLine(int line); - bool advanceToColumn(int column); - bool advanceCodePoint(bool stopOnNewLine = false); - -private: - const char * const m_utf8Text = nullptr; - - const char *m_previousByte = nullptr; - const char *m_currentByte = nullptr; -}; - -} // namespace ClangBackEnd diff --git a/src/tools/tools.qbs b/src/tools/tools.qbs index d6e7081773..cb4230dfde 100644 --- a/src/tools/tools.qbs +++ b/src/tools/tools.qbs @@ -5,7 +5,6 @@ Project { name: "Tools" references: [ "buildoutputparser/buildoutputparser.qbs", - "clangbackend/clangbackend.qbs", "cplusplustools.qbs", "disclaim/disclaim.qbs", "processlauncher/processlauncher.qbs", diff --git a/tests/unit/unittest/CMakeLists.txt b/tests/unit/unittest/CMakeLists.txt index 67213941a4..e37839e2af 100644 --- a/tests/unit/unittest/CMakeLists.txt +++ b/tests/unit/unittest/CMakeLists.txt @@ -78,7 +78,6 @@ add_qtc_test(unittest GTEST processcreator-test.cpp processevents-utilities.cpp processevents-utilities.h readandwritemessageblock-test.cpp - rundocumentparse-utility.h sizedarray-test.cpp smallstring-test.cpp sourcerangecontainer-matcher.h @@ -143,11 +142,6 @@ function(extend_qtc_test_with_target_sources target) ) endfunction() -if (HAVE_LIBCLANG AND NOT TARGET clangbackend_lib) - add_subdirectory(../../../src/tools/clangbackend/source ${CMAKE_CURRENT_BINARY_DIR}/clangbackend) -endif() -extend_qtc_test(unittest DEPENDS clangbackend_lib CONDITION HAVE_LIBCLANG) - if (NOT TARGET Sqlite) add_subdirectory(../../../src/libs/sqlite ${CMAKE_CURRENT_BINARY_DIR}/sqlite) endif() @@ -176,49 +170,8 @@ extend_qtc_test(unittest SOURCES activationsequenceprocessor-test.cpp chunksreportedmonitor.cpp - clangasyncjob-base.cpp - clangcodecompleteresults-test.cpp - clangcodemodelserver-test.cpp - clangcompletecodejob-test.cpp - clangdocumentprocessors-test.cpp - clangdocumentprocessor-test.cpp - clangdocuments-test.cpp - clangdocumentsuspenderresumer-test.cpp - clangdocument-test.cpp - clangfollowsymbol-test.cpp - clangjobqueue-test.cpp - clangjobs-test.cpp - clangparsesupportivetranslationunitjob-test.cpp - clangreferencescollector-test.cpp - clangrequestannotationsjob-test.cpp - clangrequestreferencesjob-test.cpp - clangresumedocumentjob-test.cpp - clangstring-test.cpp - clangsupportivetranslationunitinitializer-test.cpp - clangsuspenddocumentjob-test.cpp - clangtooltipinfo-test.cpp - clangtranslationunits-test.cpp - clangtranslationunit-test.cpp - clangupdateannotationsjob-test.cpp - codecompleter-test.cpp - codecompletionsextractor-test.cpp - cursor-test.cpp - diagnosticset-test.cpp - diagnostic-test.cpp - fixit-test.cpp - gtest-clang-printing.cpp gtest-clang-printing.h readexporteddiagnostics-test.cpp - skippedsourceranges-test.cpp - sourcelocation-test.cpp - sourcerange-test.cpp - token-test.cpp - tokenprocessor-test.cpp - translationunitupdater-test.cpp - unsavedfile-test.cpp - unsavedfiles-test.cpp - utf8positionfromlinecolumn-test.cpp chunksreportedmonitor.h - clangasyncjob-base.h clangcompareoperators.h diagnosticcontainer-matcher.h ) @@ -235,7 +188,6 @@ finalize_qtc_gtest(unittest ".c$") # Path needs to be before CppEditor target_include_directories(unittest PRIVATE - BEFORE ../../../src/tools/clangbackend/source BEFORE ../../../src/plugins ) diff --git a/tests/unit/unittest/clangasyncjob-base.cpp b/tests/unit/unittest/clangasyncjob-base.cpp deleted file mode 100644 index 859e0ffb79..0000000000 --- a/tests/unit/unittest/clangasyncjob-base.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangasyncjob-base.h" -#include "processevents-utilities.h" - -#include <clangsupport/filecontainer.h> - -using namespace ClangBackEnd; - -void ClangAsyncJobTest::BaseSetUp(ClangBackEnd::JobRequest::Type jobRequestType, - IAsyncJob &asyncJob) -{ - const QVector<FileContainer> fileContainer{FileContainer(filePath)}; - document = documents.create(fileContainer).front(); - documents.setVisibleInEditors({filePath}); - documents.setUsedByCurrentEditor(filePath); - - jobRequest = createJobRequest(filePath, jobRequestType); - jobContext = JobContext(jobRequest, &documents, &unsavedFiles, &dummyIpcClient); - jobContextWithMockClient = JobContext(jobRequest, &documents, &unsavedFiles, &mockIpcClient); - asyncJob.setFinishedHandler([](IAsyncJob *){}); -} - -JobRequest ClangAsyncJobTest::createJobRequest(const Utf8String &filePath, - JobRequest::Type type) const -{ - JobRequest jobRequest(type); - jobRequest.filePath = filePath; - jobRequest.unsavedFilesChangeTimePoint = unsavedFiles.lastChangeTimePoint(); - jobRequest.documentRevision = document.documentRevision(); - - return jobRequest; -} - -bool ClangAsyncJobTest::waitUntilJobFinished(const ClangBackEnd::IAsyncJob &asyncJob, - int timeOutInMs) const -{ - const auto isOnFinishedSlotExecuted = [&asyncJob](){ return asyncJob.isFinished(); }; - - return ProcessEventUtilities::processEventsUntilTrue(isOnFinishedSlotExecuted, timeOutInMs); -} diff --git a/tests/unit/unittest/clangasyncjob-base.h b/tests/unit/unittest/clangasyncjob-base.h deleted file mode 100644 index e0d7fbfa22..0000000000 --- a/tests/unit/unittest/clangasyncjob-base.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include "googletest.h" - -#include "dummyclangipcclient.h" -#include "mockclangcodemodelclient.h" - -#include <clangdocument.h> -#include <clangiasyncjob.h> -#include <clangjobrequest.h> -#include <clangdocuments.h> -#include <unsavedfiles.h> - -class ClangAsyncJobTest : public ::testing::Test -{ -protected: - void BaseSetUp(ClangBackEnd::JobRequest::Type jobRequestType, - ClangBackEnd::IAsyncJob &asyncJob); - - ClangBackEnd::JobRequest createJobRequest(const Utf8String &filePath, - ClangBackEnd::JobRequest::Type type) const; - - bool waitUntilJobFinished(const ClangBackEnd::IAsyncJob &asyncJob, - int timeOutInMs = 10000) const; - -protected: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - ClangBackEnd::Document document; - - MockClangCodeModelClient mockIpcClient; - DummyIpcClient dummyIpcClient; - - Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")}; - - ClangBackEnd::JobRequest jobRequest; - ClangBackEnd::JobContext jobContext; - ClangBackEnd::JobContext jobContextWithMockClient; -}; diff --git a/tests/unit/unittest/clangcodecompleteresults-test.cpp b/tests/unit/unittest/clangcodecompleteresults-test.cpp deleted file mode 100644 index 30356a3744..0000000000 --- a/tests/unit/unittest/clangcodecompleteresults-test.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <clangcodecompleteresults.h> -#include <clangdocument.h> -#include <clangfilepath.h> -#include <clangtranslationunitupdater.h> -#include <clangtranslationunit.h> -#include <clangdocuments.h> -#include <unsavedfiles.h> -#include <utf8string.h> - -#include <clang-c/Index.h> - -namespace { - -using ClangBackEnd::ClangCodeCompleteResults; -using ClangBackEnd::FilePath; -using ClangBackEnd::Document; -using ClangBackEnd::UnsavedFiles; - -static unsigned completionOptions() -{ - return ClangBackEnd::TranslationUnitUpdater::defaultParseOptions() - & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion - ? CXCodeComplete_IncludeBriefComments - : 0; -} - -TEST(ClangCodeCompleteResultsSlowTest, GetData) -{ - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Document document(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"), - {}, - {}, - documents); - Utf8String nativeFilePath = FilePath::toNativeSeparators(document.filePath()); - document.parse(); - CXCodeCompleteResults *cxCodeCompleteResults = - clang_codeCompleteAt(document.translationUnit().cxTranslationUnit(), - nativeFilePath.constData(), - 49, 1, 0, 0, - completionOptions()); - - ClangCodeCompleteResults codeCompleteResults(cxCodeCompleteResults); - - ASSERT_THAT(codeCompleteResults.data(), cxCodeCompleteResults); -} - -TEST(ClangCodeCompleteResults, GetInvalidData) -{ - CXCodeCompleteResults *cxCodeCompleteResults = clang_codeCompleteAt(nullptr, "file.cpp", 49, 1, 0, 0, 0); - - ClangCodeCompleteResults codeCompleteResults(cxCodeCompleteResults); - - ASSERT_THAT(codeCompleteResults.data(), cxCodeCompleteResults); -} - -TEST(ClangCodeCompleteResultsSlowTest, MoveClangCodeCompleteResults) -{ - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Document document(Utf8StringLiteral(TESTDATA_DIR"/complete_testfile_1.cpp"), - {}, - {}, - documents); - Utf8String nativeFilePath = FilePath::toNativeSeparators(document.filePath()); - document.parse(); - CXCodeCompleteResults *cxCodeCompleteResults = - clang_codeCompleteAt(document.translationUnit().cxTranslationUnit(), - nativeFilePath.constData(), - 49, 1, 0, 0, - completionOptions()); - - ClangCodeCompleteResults codeCompleteResults(cxCodeCompleteResults); - - const ClangCodeCompleteResults codeCompleteResults2 = std::move(codeCompleteResults); - - ASSERT_TRUE(codeCompleteResults.isNull()); - ASSERT_FALSE(codeCompleteResults2.isNull()); -} - -} diff --git a/tests/unit/unittest/clangcodemodelserver-test.cpp b/tests/unit/unittest/clangcodemodelserver-test.cpp deleted file mode 100644 index c74e2a96d8..0000000000 --- a/tests/unit/unittest/clangcodemodelserver-test.cpp +++ /dev/null @@ -1,753 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include "mockclangcodemodelclient.h" -#include "processevents-utilities.h" - -#include <clangcodemodelserver.h> -#include <tokeninfocontainer.h> -#include <clangcodemodelclientproxy.h> -#include <clangcodemodelserverproxy.h> -#include <clangtranslationunits.h> -#include <clangexceptions.h> - -#include <clangcodemodelservermessages.h> - -#include <clangcodemodel/clanguiheaderondiskmanager.h> - -#include <utils/algorithm.h> -#include <utils/temporarydirectory.h> - -#include <QCoreApplication> -#include <QFile> - -using testing::Property; -using testing::Contains; -using testing::Not; -using testing::Eq; -using testing::PrintToString; -using testing::_; - -namespace { - -using namespace ClangBackEnd; - -MATCHER_P4(HasDirtyDocument, - filePath, - documentRevision, - isDirty, - hasNewDiagnostics, - std::string(negation ? "isn't" : "is") - + " document with file path "+ PrintToString(filePath) - + " and document revision " + PrintToString(documentRevision) - + " and isDirty = " + PrintToString(isDirty) - + " and hasNewDiagnostics = " + PrintToString(hasNewDiagnostics) - ) -{ - auto &&documents = arg.documentsForTestOnly(); - try { - auto document = documents.document(filePath); - - if (document.documentRevision() == documentRevision) { - if (document.isDirty() && !isDirty) { - *result_listener << "isNeedingReparse is true"; - return false; - } else if (!document.isDirty() && isDirty) { - *result_listener << "isNeedingReparse is false"; - return false; - } - - return true; - } - - *result_listener << "revision number is " << PrintToString(document.documentRevision()); - return false; - - } catch (...) { - *result_listener << "has no translation unit"; - return false; - } -} - -MATCHER_P(PartlyContains, token, "") -{ - for (const auto &item: arg) { - if (item.types == token.types && item.line == token.line && item.column == token.column - && item.length == token.length) { - return true; - } - } - return false; -} - -static constexpr int AnnotationJobsMultiplier = 2; - -class ClangCodeModelServer : public ::testing::Test -{ -protected: - void SetUp() override; - void TearDown() override; - -protected: - bool waitUntilAllJobsFinished(int timeOutInMs = 10000); - - void openDocumentAndWaitForFinished( - const Utf8String &filePath, int expectedAnnotationsMessages = AnnotationJobsMultiplier); - - void openDocument(const Utf8String &filePath, - int expectedAnnotationsMessages = AnnotationJobsMultiplier); - void openDocument(const Utf8String &filePath, - const Utf8StringVector &compilationArguments, - const Utf8StringVector &headerPaths, - int expectedAnnotationsMessages = AnnotationJobsMultiplier); - void openDocuments(int expectedAnnotationsMessages); - void openDocumentWithUnsavedContent(const Utf8String &filePath, const Utf8String &content); - void closeDocument(const Utf8String &filePath); - - void updateUnsavedFile(const Utf8String &filePath, const Utf8String &fileContent); - void updateUnsavedContent(const Utf8String &filePath, - const Utf8String &fileContent, - quint32 revisionNumber); - void removeUnsavedFile(const Utf8String &filePath); - - void updateVisibilty(const Utf8String ¤tEditor, const Utf8String &additionalVisibleEditor); - - void requestAnnotations(const Utf8String &filePath); - void requestReferences(quint32 documentRevision = 0); - void requestFollowSymbol(quint32 documentRevision = 0); - void requestCompletions(const Utf8String &filePath, - uint line = 1, - uint column = 1); - void requestCompletionsInFileA(); - - bool isSupportiveTranslationUnitInitialized(const Utf8String &filePath); - - DocumentProcessor documentProcessorForFile(const Utf8String &filePath); - - void expectAnnotations(int count); - void expectCompletion(const CodeCompletion &completion); - void expectCompletionFromFileA(); - void expectCompletionFromFileAUnsavedMethodVersion1(); - void expectCompletionFromFileAUnsavedMethodVersion2(); - void expectNoCompletionWithUnsavedMethod(); - void expectReferences(); - void expectFollowSymbol(); - void expectAnnotationsForFileBWithSpecificHighlightingMark(); - - static const Utf8String unsavedContent(const QString &unsavedFilePath); - -protected: - MockClangCodeModelClient mockClangCodeModelClient; - ClangBackEnd::ClangCodeModelServer clangServer; - const ClangBackEnd::Documents &documents = clangServer.documentsForTestOnly(); - - const Utf8String filePathA = Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_function.cpp"); - const QString filePathAUnsavedVersion1 - = QStringLiteral(TESTDATA_DIR) + QStringLiteral("/complete_extractor_function_unsaved.cpp"); - const QString filePathAUnsavedVersion2 - = QStringLiteral(TESTDATA_DIR) + QStringLiteral("/complete_extractor_function_unsaved_2.cpp"); - - const Utf8String filePathB = Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_variable.cpp"); - const Utf8String filePathC = Utf8StringLiteral(TESTDATA_DIR"/references.cpp"); - - const Utf8String aFilePath = Utf8StringLiteral("afile.cpp"); - const Utf8String anExistingFilePath - = Utf8StringLiteral(TESTDATA_DIR"/complete_translationunit_parse_error.cpp"); - - const Utf8String uicMainPath = Utf8StringLiteral(TESTDATA_DIR"/uicmain.cpp"); -}; - -using ClangCodeModelServerSlowTest = ClangCodeModelServer; - -TEST_F(ClangCodeModelServerSlowTest, GetCodeCompletion) -{ - openDocument(filePathA); - - expectCompletionFromFileA(); - requestCompletionsInFileA(); -} - -TEST_F(ClangCodeModelServerSlowTest, RequestAnnotations) -{ - openDocumentAndWaitForFinished(filePathB); - - expectAnnotationsForFileBWithSpecificHighlightingMark(); - requestAnnotations(filePathB); -} - -TEST_F(ClangCodeModelServerSlowTest, RequestReferencesForCurrentDocumentRevision) -{ - openDocumentAndWaitForFinished(filePathC); - - expectReferences(); - requestReferences(); -} - -TEST_F(ClangCodeModelServerSlowTest, RequestReferencesTakesRevisionFromMessage) -{ - openDocumentAndWaitForFinished(filePathC); - - requestReferences(/*documentRevision=*/ 99); - - JobRequests &queue = documentProcessorForFile(filePathC).queue(); - ASSERT_TRUE(Utils::anyOf(queue, [](const JobRequest &request) { - return request.documentRevision == 99; - })); - queue.clear(); // Avoid blocking -} - -TEST_F(ClangCodeModelServerSlowTest, RequestFollowSymbolForCurrentDocumentRevision) -{ - openDocumentAndWaitForFinished(filePathC); - - expectFollowSymbol(); - requestFollowSymbol(); -} - -TEST_F(ClangCodeModelServerSlowTest, RequestFollowSymbolTakesRevisionFromMessage) -{ - openDocumentAndWaitForFinished(filePathC); - - requestFollowSymbol(/*documentRevision=*/ 99); - - JobRequests &queue = documentProcessorForFile(filePathC).queue(); - ASSERT_TRUE(Utils::anyOf(queue, [](const JobRequest &request) { - return request.documentRevision == 99; - })); - queue.clear(); // Avoid blocking -} - -TEST_F(ClangCodeModelServerSlowTest, NoInitialAnnotationsForClosedDocument) -{ - const int expectedAnnotationsCount = 0; - openDocument(filePathA, expectedAnnotationsCount); - - closeDocument(filePathA); -} - -TEST_F(ClangCodeModelServerSlowTest, AnnotationsForInitiallyNotVisibleDocument) -{ - const int expectedAnnotationsCount = 2; - updateVisibilty(filePathA, filePathA); - expectAnnotations(expectedAnnotationsCount); - clangServer.documentsOpened( // Open document while another is still visible - DocumentsOpenedMessage({FileContainer(filePathB, Utf8String(), false, 1)}, - filePathA, {filePathA})); - clangServer.unsavedFilesUpdated( // Invalidate added jobs - UnsavedFilesUpdatedMessage({FileContainer(Utf8StringLiteral("aFile"), Utf8String())})); - - updateVisibilty(filePathB, filePathB); -} - -TEST_F(ClangCodeModelServerSlowTest, NoAnnotationsForClosedDocument) -{ - const int expectedAnnotationsCount = AnnotationJobsMultiplier; // Only for registration. - openDocumentAndWaitForFinished(filePathA, expectedAnnotationsCount); - updateUnsavedContent(filePathA, Utf8String(), 1); - - closeDocument(filePathA); -} - -TEST_F(ClangCodeModelServerSlowTest, NoInitialAnnotationsForOutdatedDocumentRevision) -{ - const int expectedAnnotationsCount = AnnotationJobsMultiplier; // Only for registration. - openDocument(filePathA, expectedAnnotationsCount); - - updateUnsavedContent(filePathA, Utf8String(), 1); -} - -TEST_F(ClangCodeModelServerSlowTest, NoCompletionsForClosedDocument) -{ - const int expectedAnnotationsCount = AnnotationJobsMultiplier; // Only for registration. - openDocumentAndWaitForFinished(filePathA, expectedAnnotationsCount); - requestCompletionsInFileA(); - - closeDocument(filePathA); -} - -TEST_F(ClangCodeModelServerSlowTest, GetCodeCompletionForUnsavedFile) -{ - expectAnnotations(AnnotationJobsMultiplier); - openDocumentWithUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion1)); - expectCompletionFromFileAUnsavedMethodVersion1(); - - requestCompletionsInFileA(); -} - -TEST_F(ClangCodeModelServerSlowTest, GetNoCodeCompletionAfterRemovingUnsavedFile) -{ - const int expectedAnnotationsCount = 2 * AnnotationJobsMultiplier; // For registration and update/removal. - openDocumentAndWaitForFinished(filePathA, expectedAnnotationsCount); - removeUnsavedFile(filePathA); - - expectNoCompletionWithUnsavedMethod(); - requestCompletionsInFileA(); -} - -TEST_F(ClangCodeModelServerSlowTest, GetNewCodeCompletionAfterUpdatingUnsavedFile) -{ - const int expectedAnnotationsCount = 2 * AnnotationJobsMultiplier; // For registration and update/removal. - openDocumentAndWaitForFinished(filePathA, expectedAnnotationsCount); - updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 1); - - expectCompletionFromFileAUnsavedMethodVersion2(); - requestCompletionsInFileA(); -} - -TEST_F(ClangCodeModelServerSlowTest, OpenedDocumentsAreDirty) -{ - openDocument(filePathA, AnnotationJobsMultiplier); - - ASSERT_THAT(clangServer, HasDirtyDocument(filePathA, 0U, true, false)); -} - -TEST_F(ClangCodeModelServerSlowTest, SetCurrentAndVisibleEditor) -{ - openDocuments(2 * AnnotationJobsMultiplier); - ASSERT_TRUE(waitUntilAllJobsFinished()); - auto functionDocument = documents.document(filePathA); - auto variableDocument = documents.document(filePathB); - - updateVisibilty(filePathB, filePathA); - - ASSERT_TRUE(variableDocument.isUsedByCurrentEditor()); - ASSERT_TRUE(variableDocument.isVisibleInEditor()); - ASSERT_TRUE(functionDocument.isVisibleInEditor()); -} - -TEST_F(ClangCodeModelServerSlowTest, StartCompletionJobFirstOnEditThatTriggersCompletion) -{ - openDocument(filePathA, 2 * AnnotationJobsMultiplier); - ASSERT_TRUE(waitUntilAllJobsFinished()); - expectCompletionFromFileA(); - - updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 1); - requestCompletionsInFileA(); - - const QList<Jobs::RunningJob> jobs = clangServer.runningJobsForTestsOnly(); - ASSERT_THAT(jobs.size(), Eq(1)); - ASSERT_THAT(jobs.first().jobRequest.type, Eq(JobRequest::Type::RequestCompletions)); -} - -TEST_F(ClangCodeModelServerSlowTest, SupportiveTranslationUnitNotInitializedAfterRegister) -{ - openDocument(filePathA, AnnotationJobsMultiplier); - - ASSERT_TRUE(waitUntilAllJobsFinished()); - ASSERT_FALSE(isSupportiveTranslationUnitInitialized(filePathA)); -} - -TEST_F(ClangCodeModelServerSlowTest, SupportiveTranslationUnitIsSetupAfterFirstEdit) -{ - openDocument(filePathA, 2 * AnnotationJobsMultiplier); - ASSERT_TRUE(waitUntilAllJobsFinished()); - - updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 1); - - ASSERT_TRUE(waitUntilAllJobsFinished()); - ASSERT_TRUE(isSupportiveTranslationUnitInitialized(filePathA)); -} - -TEST_F(ClangCodeModelServerSlowTest, DoNotRunDuplicateJobs) -{ - openDocument(filePathA, 3 * AnnotationJobsMultiplier); - ASSERT_TRUE(waitUntilAllJobsFinished()); - updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 1); - ASSERT_TRUE(waitUntilAllJobsFinished()); - ASSERT_TRUE(isSupportiveTranslationUnitInitialized(filePathA)); - updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 2); - QCoreApplication::processEvents(); // adds + runs a job - updateVisibilty(Utf8String(), Utf8String()); - - updateVisibilty(filePathA, filePathA); // triggers adding + runnings job on next processevents() -} - -TEST_F(ClangCodeModelServerSlowTest, OpenDocumentAndEdit) -{ - openDocument(filePathA, 4 * AnnotationJobsMultiplier); - ASSERT_TRUE(waitUntilAllJobsFinished()); - - for (unsigned revision = 1; revision <= 3; ++revision) { - updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), revision); - ASSERT_TRUE(waitUntilAllJobsFinished()); - } -} - -TEST_F(ClangCodeModelServerSlowTest, IsNotCurrentCurrentAndVisibleEditorAnymore) -{ - const int expectedAnnotationsCount = 2 * AnnotationJobsMultiplier; - openDocuments(expectedAnnotationsCount); - ASSERT_TRUE(waitUntilAllJobsFinished()); - auto functionDocument = documents.document(filePathA); - auto variableDocument = documents.document(filePathB); - updateVisibilty(filePathB, filePathA); - - updateVisibilty(filePathB, Utf8String()); - - ASSERT_FALSE(functionDocument.isUsedByCurrentEditor()); - ASSERT_FALSE(functionDocument.isVisibleInEditor()); - ASSERT_TRUE(variableDocument.isUsedByCurrentEditor()); - ASSERT_TRUE(variableDocument.isVisibleInEditor()); -} - -TEST_F(ClangCodeModelServerSlowTest, TranslationUnitAfterUpdateNeedsReparse) -{ - openDocumentAndWaitForFinished(filePathA, 2 * AnnotationJobsMultiplier); - - updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion1), 1U); - ASSERT_THAT(clangServer, HasDirtyDocument(filePathA, 1U, true, true)); -} - -TEST_F(ClangCodeModelServerSlowTest, TakeOverJobsOnDocumentChange) -{ - openDocument(filePathC, AnnotationJobsMultiplier); - ASSERT_TRUE(waitUntilAllJobsFinished()); - updateVisibilty(filePathB, filePathB); // Disable processing jobs - requestReferences(); - - expectReferences(); - - openDocument(filePathC, AnnotationJobsMultiplier); // Do not loose jobs - updateVisibilty(filePathC, filePathC); // Enable processing jobs -} - -TEST_F(ClangCodeModelServerSlowTest, UicHeaderAvailableBeforeParse) -{ - // Write ui file - ClangCodeModel::Internal::UiHeaderOnDiskManager uiManager; - const QByteArray content = "class UicObject{};"; - const QString uiHeaderFilePath = uiManager.write("uicheader.h", content); - - // Open document - openDocument(uicMainPath, - {Utf8StringLiteral("-I"), Utf8String(uiManager.directoryPath())}, - {uiManager.directoryPath()}, - AnnotationJobsMultiplier); - updateVisibilty(uicMainPath, uicMainPath); - ASSERT_TRUE(waitUntilAllJobsFinished()); - - // Check - ASSERT_THAT(documents.document(uicMainPath).dependedFilePaths(), - Contains(uiHeaderFilePath)); -} - -TEST_F(ClangCodeModelServerSlowTest, UicHeaderAvailableAfterParse) -{ - ClangCodeModel::Internal::UiHeaderOnDiskManager uiManager; - const QString uiHeaderFilePath = uiManager.mapPath("uicheader.h"); - - // Open document - openDocument(uicMainPath, - {Utf8StringLiteral("-I"), Utf8String(uiManager.directoryPath())}, - {uiManager.directoryPath()}, - 2 * AnnotationJobsMultiplier); - updateVisibilty(uicMainPath, uicMainPath); - ASSERT_TRUE(waitUntilAllJobsFinished()); - ASSERT_THAT(documents.document(uicMainPath).dependedFilePaths(), - Not(Contains(uiHeaderFilePath))); - - // Write ui file and notify backend - const QByteArray content = "class UicObject{};"; - uiManager.write("uicheader.h", content); - updateUnsavedFile(Utf8String(uiHeaderFilePath), Utf8String::fromByteArray(content)); - - // Check - ASSERT_TRUE(waitUntilAllJobsFinished()); - ASSERT_THAT(documents.document(uicMainPath).dependedFilePaths(), - Contains(uiHeaderFilePath)); -} - -void ClangCodeModelServer::SetUp() -{ - clangServer.setClient(&mockClangCodeModelClient); - clangServer.setUpdateAnnotationsTimeOutInMsForTestsOnly(0); - clangServer.setUpdateVisibleButNotCurrentDocumentsTimeOutInMsForTestsOnly(0); -} - -void ClangCodeModelServer::TearDown() -{ - ASSERT_TRUE(waitUntilAllJobsFinished()); -} - -bool ClangCodeModelServer::waitUntilAllJobsFinished(int timeOutInMs) -{ - const auto noJobsRunningAnymore = [this]() { - return clangServer.runningJobsForTestsOnly().isEmpty() - && clangServer.queueSizeForTestsOnly() == 0 - && !clangServer.isTimerRunningForTestOnly(); - }; - - return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs); -} - -void ClangCodeModelServer::openDocument(const Utf8String &filePath, - int expectedAnnotationsMessages) -{ - openDocument(filePath, {}, {}, expectedAnnotationsMessages); -} - -void ClangCodeModelServer::openDocument(const Utf8String &filePath, - const Utf8StringVector &compilationArguments, - const Utf8StringVector &headerPaths, - int expectedAnnotationsMessages) -{ - const FileContainer fileContainer(filePath, compilationArguments, headerPaths); - const DocumentsOpenedMessage message({fileContainer}, filePath, {filePath}); - - expectAnnotations(expectedAnnotationsMessages); - - clangServer.documentsOpened(message); -} - -void ClangCodeModelServer::openDocuments(int expectedAnnotationsMessages) -{ - const FileContainer fileContainerA(filePathA); - const FileContainer fileContainerB(filePathB); - const DocumentsOpenedMessage message({fileContainerA, fileContainerB}, - filePathA, - {filePathA, filePathB}); - - expectAnnotations(expectedAnnotationsMessages); - - clangServer.documentsOpened(message); -} - -void ClangCodeModelServer::expectAnnotations(int count) -{ - EXPECT_CALL(mockClangCodeModelClient, annotations(_)).Times(count); -} - -void ClangCodeModelServer::openDocumentWithUnsavedContent(const Utf8String &filePath, - const Utf8String &unsavedContent) -{ - const FileContainer fileContainer(filePath, unsavedContent, true); - const DocumentsOpenedMessage message({fileContainer}, filePath, {filePath}); - - clangServer.documentsOpened(message); -} - -void ClangCodeModelServer::requestCompletions(const Utf8String &filePath, uint line, uint column) -{ - const RequestCompletionsMessage message(filePath, line, column); - - clangServer.requestCompletions(message); -} - -void ClangCodeModelServer::requestCompletionsInFileA() -{ - requestCompletions(filePathA, 20, 1); -} - -bool ClangCodeModelServer::isSupportiveTranslationUnitInitialized(const Utf8String &filePath) -{ - Document document = clangServer.documentsForTestOnly().document(filePath); - DocumentProcessor documentProcessor = clangServer.documentProcessors().processor(document); - - return document.translationUnits().size() == 2 - && documentProcessor.hasSupportiveTranslationUnit() - && documentProcessor.isSupportiveTranslationUnitInitialized(); -} - -DocumentProcessor ClangCodeModelServer::documentProcessorForFile(const Utf8String &filePath) -{ - Document document = clangServer.documentsForTestOnly().document(filePath); - DocumentProcessor documentProcessor = clangServer.documentProcessors().processor(document); - - return documentProcessor; -} - -void ClangCodeModelServer::expectCompletion(const CodeCompletion &completion) -{ - EXPECT_CALL(mockClangCodeModelClient, - completions(Field(&CompletionsMessage::codeCompletions, - Contains(completion)))) - .Times(1); -} - -void ClangCodeModelServer::expectCompletionFromFileAUnsavedMethodVersion1() -{ - const CodeCompletion completion(Utf8StringLiteral("Method2"), - 34, - CodeCompletion::FunctionDefinitionCompletionKind); - - expectCompletion(completion); -} - -void ClangCodeModelServer::expectCompletionFromFileAUnsavedMethodVersion2() -{ - const CodeCompletion completion(Utf8StringLiteral("Method3"), - 34, - CodeCompletion::FunctionDefinitionCompletionKind); - - expectCompletion(completion); -} - -void ClangCodeModelServer::expectNoCompletionWithUnsavedMethod() -{ - const CodeCompletion completion(Utf8StringLiteral("Method2"), - 34, - CodeCompletion::FunctionCompletionKind); - - EXPECT_CALL(mockClangCodeModelClient, - completions(Field(&CompletionsMessage::codeCompletions, - Not(Contains(completion))))) - .Times(1); -} - -void ClangCodeModelServer::expectReferences() -{ - const QVector<ClangBackEnd::SourceRangeContainer> references{{ - {filePathC, 3, 9}, - {filePathC, 3, 12} - }}; - - EXPECT_CALL(mockClangCodeModelClient, - references( - Field(&ReferencesMessage::references, - Eq(references)))) - .Times(1); -} - -void ClangCodeModelServer::expectFollowSymbol() -{ - const ClangBackEnd::FollowSymbolResult classDefinition - = ClangBackEnd::SourceRangeContainer({filePathC, 40, 7}, {filePathC, 40, 10}); - - EXPECT_CALL(mockClangCodeModelClient, - followSymbol( - Field(&FollowSymbolMessage::result, - Eq(classDefinition)))) - .Times(1); -} - -void ClangCodeModelServer::expectCompletionFromFileA() -{ - const CodeCompletion completion(Utf8StringLiteral("Function"), - 34, - CodeCompletion::FunctionCompletionKind); - - expectCompletion(completion); -} - -void ClangCodeModelServer::requestAnnotations(const Utf8String &filePath) -{ - const RequestAnnotationsMessage message(FileContainer{filePath}); - - clangServer.requestAnnotations(message); -} - -void ClangCodeModelServer::requestReferences(quint32 documentRevision) -{ - const FileContainer fileContainer{filePathC, {}, {}, documentRevision}; - const RequestReferencesMessage message{fileContainer, 3, 9}; - - clangServer.requestReferences(message); -} - -void ClangCodeModelServer::requestFollowSymbol(quint32 documentRevision) -{ - const FileContainer fileContainer{filePathC, {}, {}, documentRevision}; - const RequestFollowSymbolMessage message{fileContainer, 43, 9}; - - clangServer.requestFollowSymbol(message); -} - -void ClangCodeModelServer::expectAnnotationsForFileBWithSpecificHighlightingMark() -{ - HighlightingTypes types; - types.mainHighlightingType = ClangBackEnd::HighlightingType::Function; - types.mixinHighlightingTypes.push_back(ClangBackEnd::HighlightingType::Declaration); - types.mixinHighlightingTypes.push_back(ClangBackEnd::HighlightingType::FunctionDefinition); - const TokenInfoContainer tokenInfo(1, 6, 8, types); - EXPECT_CALL(mockClangCodeModelClient, - annotations( - Field(&AnnotationsMessage::tokenInfos, - PartlyContains(tokenInfo)))).Times(AnnotationJobsMultiplier); -} - -void ClangCodeModelServer::updateUnsavedContent(const Utf8String &filePath, - const Utf8String &fileContent, - quint32 revisionNumber) -{ - const FileContainer fileContainer(filePath, fileContent, true, revisionNumber); - const DocumentsChangedMessage message({fileContainer}); - - clangServer.documentsChanged(message); -} - -void ClangCodeModelServer::removeUnsavedFile(const Utf8String &filePath) -{ - const FileContainer fileContainer(filePath, {}, {}, 74); - const DocumentsChangedMessage message({fileContainer}); - - clangServer.documentsChanged(message); -} - -void ClangCodeModelServer::closeDocument(const Utf8String &filePath) -{ - const QVector<FileContainer> fileContainers = {FileContainer(filePath)}; - const DocumentsClosedMessage message(fileContainers); - - clangServer.documentsClosed(message); -} - -void ClangCodeModelServer::updateUnsavedFile(const Utf8String &filePath, - const Utf8String &fileContent) -{ - const FileContainer fileContainer(filePath, fileContent, true, 0); - const UnsavedFilesUpdatedMessage message({fileContainer}); - - clangServer.unsavedFilesUpdated(message); -} - -void ClangCodeModelServer::openDocumentAndWaitForFinished( - const Utf8String &filePath, int expectedAnnotationsMessages) -{ - openDocument(filePath, expectedAnnotationsMessages); - ASSERT_TRUE(waitUntilAllJobsFinished()); -} - -void ClangCodeModelServer::updateVisibilty(const Utf8String ¤tEditor, - const Utf8String &additionalVisibleEditor) -{ - const DocumentVisibilityChangedMessage message(currentEditor, - {currentEditor, additionalVisibleEditor}); - - clangServer.documentVisibilityChanged(message); -} - -const Utf8String ClangCodeModelServer::unsavedContent(const QString &unsavedFilePath) -{ - QFile unsavedFileContentFile(unsavedFilePath); - const bool isOpen = unsavedFileContentFile.open(QIODevice::ReadOnly | QIODevice::Text); - if (!isOpen) - ADD_FAILURE() << "File with the unsaved content cannot be opened!"; - - return Utf8String::fromByteArray(unsavedFileContentFile.readAll()); -} - -} // anonymous diff --git a/tests/unit/unittest/clangcompletecodejob-test.cpp b/tests/unit/unittest/clangcompletecodejob-test.cpp deleted file mode 100644 index 025a4b4f4e..0000000000 --- a/tests/unit/unittest/clangcompletecodejob-test.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangasyncjob-base.h" - -#include <clangcompletecodejob.h> - -using namespace ClangBackEnd; - -using testing::_; -using testing::Eq; -using testing::Property; - -namespace { - -class CompleteCodeJob : public ClangAsyncJobTest -{ -protected: - void SetUp() override { BaseSetUp(JobRequest::Type::RequestCompletions, job); } - -protected: - ClangBackEnd::CompleteCodeJob job; -}; - -TEST_F(CompleteCodeJob, PrepareAsyncRun) -{ - job.setContext(jobContext); - - ASSERT_TRUE(job.prepareAsyncRun()); -} - -TEST_F(CompleteCodeJob, RunAsync) -{ - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(CompleteCodeJob, SendAnnotations) -{ - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, completions(_)).Times(1); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(CompleteCodeJob, ForwardTicketNumber) -{ - jobRequest.ticketNumber = static_cast<quint64>(99); - jobContextWithMockClient = JobContext(jobRequest, &documents, &unsavedFiles, &mockIpcClient); - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, - completions(Field(&CompletionsMessage::ticketNumber, - Eq(jobRequest.ticketNumber)))) - .Times(1); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(CompleteCodeJob, DontSendCompletionsIfDocumentWasClosed) -{ - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, completions(_)).Times(0); - - job.runAsync(); - documents.remove({FileContainer{filePath}}); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -} // anonymous diff --git a/tests/unit/unittest/clangdocument-test.cpp b/tests/unit/unittest/clangdocument-test.cpp deleted file mode 100644 index 4978f41fd7..0000000000 --- a/tests/unit/unittest/clangdocument-test.cpp +++ /dev/null @@ -1,361 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <clangclock.h> -#include <clangfilepath.h> -#include <clangtranslationunitupdater.h> -#include <clangtranslationunits.h> -#include <clangtranslationunit.h> -#include <commandlinearguments.h> -#include <diagnosticset.h> -#include <tokenprocessor.h> -#include <filecontainer.h> -#include <clangexceptions.h> -#include <clangdocument.h> -#include <clangtranslationunit.h> -#include <clangdocuments.h> -#include <unsavedfiles.h> -#include <utf8string.h> - -#include <clang-c/Index.h> - -#include <QTemporaryFile> - -#include <thread> - -using ClangBackEnd::Clock; -using ClangBackEnd::Duration; -using ClangBackEnd::FileContainer; -using ClangBackEnd::FilePath; -using ClangBackEnd::Document; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::Documents; -using ClangBackEnd::TranslationUnitUpdateResult; -using ClangBackEnd::TranslationUnit; -using ClangBackEnd::TranslationUnits; - -using testing::IsNull; -using testing::NotNull; -using testing::Eq; -using testing::Gt; -using testing::Contains; -using testing::EndsWith; -using testing::AllOf; - -namespace { - -class Document : public ::testing::Test -{ -protected: - void SetUp() override; - ::Document createDocumentAndDeleteFile(); - QByteArray readContentFromDocumentFile() const; - -protected: - Utf8String documentFilePath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp"); - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - ::Document document; -}; - -using DocumentSlowTest = Document; - -TEST_F(Document, DefaultDocumentIsInvalid) -{ - ::Document document; - - ASSERT_TRUE(document.isNull()); -} - -TEST_F(Document, DefaultDocumentIsNotIntact) -{ - ::Document document; - - ASSERT_FALSE(document.isIntact()); -} - -TEST_F(Document, ThrowExceptionForNonExistingFilePath) -{ - ASSERT_THROW(::Document(Utf8StringLiteral("file.cpp"), {}, {}, documents), - ClangBackEnd::DocumentFileDoesNotExistException); -} - -TEST_F(Document, ThrowNoExceptionForNonExistingFilePathIfDoNotCheckIfFileExistsIsSet) -{ - ASSERT_NO_THROW(::Document(Utf8StringLiteral("file.cpp"), - {}, - {}, - documents, - ::Document::FileExistsCheck::DoNotCheck)); -} - -TEST_F(Document, DocumentIsValid) -{ - ASSERT_FALSE(document.isNull()); -} - - -TEST_F(Document, ThrowExceptionForGettingIndexForInvalidUnit) -{ - ::Document document; - - ASSERT_THROW(document.translationUnit().cxIndex(), ClangBackEnd::DocumentIsNullException); -} - -TEST_F(Document, ThrowExceptionForGettingCxTranslationUnitForInvalidUnit) -{ - ::Document document; - - ASSERT_THROW(document.translationUnit().cxIndex(), ClangBackEnd::DocumentIsNullException); -} - -TEST_F(DocumentSlowTest, CxTranslationUnitGetterIsNonNullForParsedUnit) -{ - document.parse(); - - ASSERT_THAT(document.translationUnit().cxIndex(), NotNull()); -} - -TEST_F(Document, ThrowExceptionIfGettingFilePathForNullUnit) -{ - ::Document document; - - ASSERT_THROW(document.filePath(), ClangBackEnd::DocumentIsNullException); -} - -TEST_F(Document, ResettedDocumentIsNull) -{ - document.reset(); - - ASSERT_TRUE(document.isNull()); -} - -TEST_F(Document, LastCommandLineArgumentIsFilePath) -{ - const Utf8String nativeFilePath = FilePath::toNativeSeparators(documentFilePath); - const auto arguments = document.createUpdater().commandLineArguments(); - - ASSERT_THAT(arguments.at(arguments.count() - 1), Eq(nativeFilePath)); -} - -TEST_F(Document, DocumentRevisionInFileContainerGetter) -{ - document.setDocumentRevision(74); - - ASSERT_THAT(document.fileContainer().documentRevision, 74); -} - -TEST_F(DocumentSlowTest, DependedFilePaths) -{ - document.parse(); - - ASSERT_THAT(document.dependedFilePaths(), - AllOf(Contains(documentFilePath), - Contains(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h")))); -} - -TEST_F(Document, DeletedFileShouldNotNeedReparsing) -{ - auto document = createDocumentAndDeleteFile(); - - document.setDirtyIfDependencyIsMet(document.filePath()); - - ASSERT_FALSE(document.isDirty()); -} - -TEST_F(Document, NeedsNoReparseAfterCreation) -{ - ASSERT_FALSE(document.isDirty()); -} - -TEST_F(DocumentSlowTest, NeedsReparseAfterChangeOfMainFile) -{ - document.parse(); - - document.setDirtyIfDependencyIsMet(documentFilePath); - - ASSERT_TRUE(document.isDirty()); -} - -TEST_F(DocumentSlowTest, NoNeedForReparsingForIndependentFile) -{ - document.parse(); - - document.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/otherfiles.h")); - - ASSERT_FALSE(document.isDirty()); -} - -TEST_F(DocumentSlowTest, NeedsReparsingForDependentFile) -{ - document.parse(); - - document.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h")); - - ASSERT_TRUE(document.isDirty()); -} - -TEST_F(DocumentSlowTest, NeedsNoReparsingAfterReparsing) -{ - document.parse(); - document.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h")); - - document.reparse(); - - ASSERT_FALSE(document.isDirty()); -} - -TEST_F(DocumentSlowTest, IsIntactAfterParsing) -{ - document.parse(); - - ASSERT_TRUE(document.isIntact()); -} - -TEST_F(Document, IsNotIntactForDeletedFile) -{ - auto document = createDocumentAndDeleteFile(); - - ASSERT_FALSE(document.isIntact()); -} - -TEST_F(DocumentSlowTest, DoesNotNeedReparseAfterParse) -{ - document.parse(); - - ASSERT_FALSE(document.isDirty()); -} - -TEST_F(DocumentSlowTest, NeedsReparseAfterMainFileChanged) -{ - document.parse(); - - document.setDirtyIfDependencyIsMet(documentFilePath); - - ASSERT_TRUE(document.isDirty()); -} - -TEST_F(DocumentSlowTest, NeedsReparseAfterIncludedFileChanged) -{ - document.parse(); - - document.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/translationunits.h")); - - ASSERT_TRUE(document.isDirty()); -} - -TEST_F(DocumentSlowTest, DoesNotNeedReparseAfterNotIncludedFileChanged) -{ - document.parse(); - - document.setDirtyIfDependencyIsMet(Utf8StringLiteral(TESTDATA_DIR"/otherfiles.h")); - - ASSERT_FALSE(document.isDirty()); -} - -TEST_F(DocumentSlowTest, DoesNotNeedReparseAfterReparse) -{ - document.parse(); - document.setDirtyIfDependencyIsMet(documentFilePath); - - document.reparse(); - - ASSERT_FALSE(document.isDirty()); -} - -TEST_F(Document, IncorporateUpdaterResultResetsDirtyness) -{ - document.setDirtyIfDependencyIsMet(document.filePath()); - TranslationUnitUpdateResult result; - result.reparseTimePoint = Clock::now(); - result.needsToBeReparsedChangeTimePoint = document.isDirtyTimeChangePoint(); - result.translationUnitId = document.translationUnit().id(); - - document.incorporateUpdaterResult(result); - - ASSERT_FALSE(document.isDirty()); -} - -TEST_F(Document, IncorporateUpdaterResultDoesNotResetDirtynessIfItWasChanged) -{ - TranslationUnitUpdateResult result; - result.reparseTimePoint = Clock::now(); - result.needsToBeReparsedChangeTimePoint = Clock::now(); - result.translationUnitId = document.translationUnit().id(); - document.setDirtyIfDependencyIsMet(document.filePath()); - - document.incorporateUpdaterResult(result); - - ASSERT_TRUE(document.isDirty()); -} - -TEST_F(Document, IncorporateUpdaterResultUpdatesTranslationUnitsReparseTimePoint) -{ - TranslationUnits &translationUnits = document.translationUnits(); - const TranslationUnit initialTranslationUnit = translationUnits.get(); - translationUnits.updateParseTimePoint(initialTranslationUnit.id(), Clock::now()); - const TranslationUnit alternativeTranslationUnit = translationUnits.createAndAppend(); - translationUnits.updateParseTimePoint(alternativeTranslationUnit.id(), Clock::now()); - TranslationUnitUpdateResult result; - result.reparseTimePoint = Clock::now(); - result.needsToBeReparsedChangeTimePoint = Clock::now(); - result.translationUnitId = initialTranslationUnit.id(); - document.setDirtyIfDependencyIsMet(document.filePath()); - ASSERT_THAT(translationUnits.get().id(), Eq(alternativeTranslationUnit.id())); - - document.incorporateUpdaterResult(result); - - ASSERT_THAT(translationUnits.get().id(), Eq(initialTranslationUnit.id())); -} - -void Document::SetUp() -{ - const QVector<FileContainer> fileContainer{FileContainer(documentFilePath)}; - const auto createdDocuments = documents.create(fileContainer); - document = createdDocuments.front(); -} - -::Document Document::createDocumentAndDeleteFile() -{ - QTemporaryFile temporaryFile; - EXPECT_TRUE(temporaryFile.open()); - EXPECT_TRUE(temporaryFile.write(readContentFromDocumentFile())); - ::Document document(temporaryFile.fileName(), {}, {}, documents); - - return document; -} - -QByteArray Document::readContentFromDocumentFile() const -{ - QFile contentFile(documentFilePath); - EXPECT_TRUE(contentFile.open(QIODevice::ReadOnly)); - - return contentFile.readAll(); -} - -} - diff --git a/tests/unit/unittest/clangdocumentprocessor-test.cpp b/tests/unit/unittest/clangdocumentprocessor-test.cpp deleted file mode 100644 index 5ed3fd328d..0000000000 --- a/tests/unit/unittest/clangdocumentprocessor-test.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include "clangiasyncjob.h" -#include "dummyclangipcclient.h" -#include "processevents-utilities.h" - -#include <clangdocument.h> -#include <clangdocumentprocessor.h> -#include <clangdocuments.h> -#include <clangjobrequest.h> -#include <clangjobs.h> -#include <unsavedfiles.h> - -using namespace ClangBackEnd; - -namespace { - -class DocumentProcessor : public ::testing::Test -{ -protected: - void SetUp() override; - void TearDown() override; - bool waitUntilAllJobsFinished(int timeOutInMs = 10000) const; - -protected: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - - DummyIpcClient dummyIpcClient; - - Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")}; - std::unique_ptr<ClangBackEnd::DocumentProcessor> documentProcessor; -}; - -using DocumentProcessorSlowTest = DocumentProcessor; - -TEST_F(DocumentProcessor, ProcessEmpty) -{ - const JobRequests jobsStarted = documentProcessor->process(); - - ASSERT_THAT(jobsStarted.size(), 0); -} - -TEST_F(DocumentProcessorSlowTest, ProcessSingleJob) -{ - const JobRequest jobRequest - = documentProcessor->createJobRequest(JobRequest::Type::UpdateAnnotations); - documentProcessor->addJob(jobRequest); - - const JobRequests jobsStarted = documentProcessor->process(); - - ASSERT_THAT(jobsStarted.size(), 1); -} - -void DocumentProcessor::SetUp() -{ - const QVector<FileContainer> fileContainer{FileContainer(filePath)}; - - ClangBackEnd::Document document = {documents.create(fileContainer).front()}; - documents.setVisibleInEditors({filePath}); - documents.setUsedByCurrentEditor(filePath); - documentProcessor = std::make_unique<ClangBackEnd::DocumentProcessor>( - document, documents, unsavedFiles, dummyIpcClient); -} - -void DocumentProcessor::TearDown() -{ - ASSERT_TRUE(waitUntilAllJobsFinished()); // QFuture/QFutureWatcher is implemented with events -} - -bool DocumentProcessor::waitUntilAllJobsFinished(int timeOutInMs) const -{ - const auto noJobsRunningAnymore = [this](){ return documentProcessor->runningJobs().isEmpty(); }; - - return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs); -} - -} // anonymous diff --git a/tests/unit/unittest/clangdocumentprocessors-test.cpp b/tests/unit/unittest/clangdocumentprocessors-test.cpp deleted file mode 100644 index 62a5d47543..0000000000 --- a/tests/unit/unittest/clangdocumentprocessors-test.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include "clangiasyncjob.h" -#include "dummyclangipcclient.h" -#include "processevents-utilities.h" - -#include <clangdocument.h> -#include <clangdocumentprocessor.h> -#include <clangdocumentprocessors.h> -#include <clangdocuments.h> -#include <clangexceptions.h> -#include <clangjobrequest.h> -#include <clangjobs.h> -#include <unsavedfiles.h> - -using testing::Eq; - -using namespace ClangBackEnd; - -namespace { - -class DocumentProcessors : public ::testing::Test -{ -protected: - void SetUp() override; - void TearDown() override; - - bool waitUntilAllJobsFinished(int timeOutInMs = 10000) const; - -protected: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - ClangBackEnd::Document document; - - DummyIpcClient dummyIpcClient; - - Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")}; - - ClangBackEnd::JobRequest jobRequest; - ClangBackEnd::JobContext jobContext; - - ClangBackEnd::DocumentProcessors documentProcessors{documents, - unsavedFiles, - dummyIpcClient}; -}; - -using DocumentProcessorsSlowTest = DocumentProcessors; - -TEST_F(DocumentProcessors, HasNoItemsInitially) -{ - ASSERT_TRUE(documentProcessors.processors().empty()); -} - -TEST_F(DocumentProcessors, CreateAddsADocumentProcessor) -{ - documentProcessors.create(document); - - ASSERT_THAT(documentProcessors.processors().size(), Eq(1)); -} - -TEST_F(DocumentProcessors, CreateReturnsDocumentProcessor) -{ - const DocumentProcessor documentProcessor = documentProcessors.create(document); - - ASSERT_THAT(documentProcessor.document(), Eq(document)); -} - -TEST_F(DocumentProcessors, CreateThrowsForAlreadyExisting) -{ - documentProcessors.create(document); - - ASSERT_THROW(documentProcessors.create(document), - ClangBackEnd::DocumentProcessorAlreadyExists); -} - -TEST_F(DocumentProcessors, Access) -{ - documentProcessors.create(document); - - const DocumentProcessor documentProcessor = documentProcessors.processor(document); - - ASSERT_THAT(documentProcessor.document(), Eq(document)); -} - -TEST_F(DocumentProcessors, AccessThrowsForNotExisting) -{ - ASSERT_THROW(documentProcessors.processor(document), - ClangBackEnd::DocumentProcessorDoesNotExist); -} - -TEST_F(DocumentProcessors, Remove) -{ - documentProcessors.create(document); - - documentProcessors.remove(document); - - ASSERT_TRUE(documentProcessors.processors().empty()); -} - -TEST_F(DocumentProcessors, ResetTakesOverJobsInQueue) -{ - documentProcessors.create(document); - documentProcessors.processor(document).addJob(JobRequest::Type::RequestReferences); - documents.remove({document.fileContainer()}); - const auto newDocument = *documents.create({document.fileContainer()}).begin(); - - documentProcessors.reset(document, newDocument); - - ASSERT_THAT(documentProcessors.processor(document).queue().first().type, - JobRequest::Type::RequestReferences); -} - -TEST_F(DocumentProcessors, RemoveThrowsForNotExisting) -{ - ASSERT_THROW(documentProcessors.remove(document), - ClangBackEnd::DocumentProcessorDoesNotExist); -} - -TEST_F(DocumentProcessors, ProcessEmpty) -{ - documentProcessors.create(document); - - const JobRequests jobsStarted = documentProcessors.process(); - - ASSERT_TRUE(jobsStarted.isEmpty()); -} - -TEST_F(DocumentProcessorsSlowTest, ProcessSingle) -{ - DocumentProcessor documentProcessor = documentProcessors.create(document); - documentProcessor.addJob(JobRequest::Type::UpdateAnnotations); - - const JobRequests jobsStarted = documentProcessors.process(); - - ASSERT_THAT(jobsStarted.size(), 1); -} - -void DocumentProcessors::SetUp() -{ - const QVector<FileContainer> fileContainer{FileContainer(filePath)}; - document = documents.create(fileContainer).front(); - documents.setVisibleInEditors({filePath}); - documents.setUsedByCurrentEditor(filePath); -} - -void DocumentProcessors::TearDown() -{ - ASSERT_TRUE(waitUntilAllJobsFinished()); // QFuture/QFutureWatcher is implemented with events -} - -bool DocumentProcessors::waitUntilAllJobsFinished(int timeOutInMs) const -{ - const auto noJobsRunningAnymore = [this](){ return documentProcessors.runningJobs().isEmpty(); }; - - return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs); -} - -} // anonymous diff --git a/tests/unit/unittest/clangdocuments-test.cpp b/tests/unit/unittest/clangdocuments-test.cpp deleted file mode 100644 index 71a2ebed80..0000000000 --- a/tests/unit/unittest/clangdocuments-test.cpp +++ /dev/null @@ -1,377 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <clangexceptions.h> -#include <clangdocument.h> -#include <clangdocuments.h> -#include <unsavedfiles.h> -#include <utf8string.h> - -#include <clang-c/Index.h> - -using ClangBackEnd::Document; -using ClangBackEnd::UnsavedFiles; - -using testing::IsNull; -using testing::NotNull; -using testing::Gt; -using testing::Eq; -using testing::Not; -using testing::Contains; - -namespace { - -using ::testing::PrintToString; - -MATCHER_P2(IsDocument, filePath, documentRevision, - std::string(negation ? "isn't" : "is") - + " document with file path "+ PrintToString(filePath) - + " and document revision " + PrintToString(documentRevision) - ) -{ - return arg.filePath() == filePath - && arg.documentRevision() == documentRevision; -} - -class Documents : public ::testing::Test -{ -protected: - void SetUp() override; - -protected: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - const Utf8String filePath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp"); - const Utf8String otherFilePath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.h"); - const Utf8String headerPath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.h"); - const Utf8String nonExistingFilePath = Utf8StringLiteral("foo.cpp"); - const ClangBackEnd::FileContainer fileContainer{filePath}; - const ClangBackEnd::FileContainer headerContainer{headerPath}; -}; - -using DocumentsSlowTest = Documents; - -TEST_F(Documents, ThrowForGettingWithWrongFilePath) -{ - ASSERT_THROW(documents.document(nonExistingFilePath), - ClangBackEnd::DocumentDoesNotExistException); - -} - -TEST_F(Documents, ThrowForAddingNonExistingFile) -{ - ClangBackEnd::FileContainer fileContainer(nonExistingFilePath); - - ASSERT_THROW(documents.create({fileContainer}), - ClangBackEnd::DocumentFileDoesNotExistException); -} - -TEST_F(Documents, DoNotThrowForAddingNonExistingFileWithUnsavedContent) -{ - ClangBackEnd::FileContainer fileContainer(nonExistingFilePath, Utf8String(), true); - - ASSERT_NO_THROW(documents.create({fileContainer})); -} - -TEST_F(Documents, Add) -{ - ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); - - documents.create({fileContainer}); - - ASSERT_THAT(documents.document(filePath), - IsDocument(filePath, 74u)); -} - -TEST_F(Documents, CreateWithUnsavedContentSetsDependenciesDirty) -{ - ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); - ClangBackEnd::FileContainer fileContainerWithUnsavedContent(otherFilePath, {}, {}, Utf8String(), true, 2u); - auto dependentDocument = documents.create({fileContainer}).at(0); - dependentDocument.setDependedFilePaths(QSet<Utf8String>() << filePath << otherFilePath); - - documents.create({fileContainerWithUnsavedContent}); - - ASSERT_TRUE(dependentDocument.isDirty()); -} - -TEST_F(Documents, AddAndTestCreatedTranslationUnit) -{ - ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); - - auto createdDocuments = documents.create({fileContainer}); - - ASSERT_THAT(createdDocuments.front(), IsDocument(filePath, 74u)); -} - -TEST_F(Documents, ThrowForCreatingAnExistingDocument) -{ - ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); - documents.create({fileContainer}); - - ASSERT_THROW(documents.create({fileContainer}), ClangBackEnd::DocumentAlreadyExistsException); -} - -TEST_F(Documents, ThrowForUpdatingANonExistingDocument) -{ - ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); - ASSERT_THROW(documents.update({fileContainer}), - ClangBackEnd::DocumentDoesNotExistException); -} - -TEST_F(Documents, UpdateSingle) -{ - ClangBackEnd::FileContainer createFileContainer(filePath, {}, {}, 74u); - ClangBackEnd::FileContainer updateFileContainer(filePath, {}, {}, 75u); - documents.create({createFileContainer}); - - documents.update({updateFileContainer}); - - ASSERT_THAT(documents.document(filePath), IsDocument(filePath, 75u)); -} - -TEST_F(Documents, UpdateReturnsUpdatedDocument) -{ - ClangBackEnd::FileContainer createFileContainer(filePath, {}, {}, 74u); - ClangBackEnd::FileContainer updateFileContainer(filePath, {}, {}, 75u); - documents.create({createFileContainer}); - - const std::vector<Document> updatedDocuments = documents.update({updateFileContainer}); - - ASSERT_THAT(updatedDocuments.size(), Eq(1u)); - ASSERT_THAT(updatedDocuments.front().documentRevision(), Eq(75u)); -} - -// TODO: Does this test still makes sense? -TEST_F(Documents, UpdateMultiple) -{ - ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); - ClangBackEnd::FileContainer fileContainerWithOtherProject(filePath, {}, {}, 74u); - ClangBackEnd::FileContainer updatedFileContainer(filePath, {}, {}, 75u); - documents.create({fileContainer, fileContainerWithOtherProject}); - - documents.update({updatedFileContainer}); - - ASSERT_THAT(documents.document(filePath), IsDocument(filePath, 75u)); -} - -TEST_F(DocumentsSlowTest, UpdateUnsavedFileAndCheckForReparse) -{ - ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); - ClangBackEnd::FileContainer headerContainer(headerPath, {}, {}, 74u); - ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, Utf8String(), true, 75u); - documents.create({fileContainer, headerContainer}); - Document document = documents.document(filePath); - document.parse(); - - documents.update({headerContainerWithUnsavedContent}); - - ASSERT_TRUE(documents.document(filePath).isDirty()); -} - -TEST_F(DocumentsSlowTest, RemoveFileAndCheckForReparse) -{ - ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); - ClangBackEnd::FileContainer headerContainer(headerPath, {}, {}, 74u); - ClangBackEnd::FileContainer headerContainerWithUnsavedContent(headerPath, Utf8String(), true, 75u); - documents.create({fileContainer, headerContainer}); - Document document = documents.document(filePath); - document.parse(); - - documents.remove({headerContainerWithUnsavedContent}); - - ASSERT_TRUE(documents.document(filePath).isDirty()); -} - -TEST_F(Documents, DontGetNewerFileContainerIfRevisionIsTheSame) -{ - ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); - documents.create({fileContainer}); - - auto newerFileContainers = documents.newerFileContainers({fileContainer}); - - ASSERT_THAT(newerFileContainers.size(), 0); -} - -TEST_F(Documents, GetNewerFileContainerIfRevisionIsDifferent) -{ - ClangBackEnd::FileContainer fileContainer(filePath, {}, {}, 74u); - ClangBackEnd::FileContainer newerContainer(filePath, {}, {}, 75u); - documents.create({fileContainer}); - - auto newerFileContainers = documents.newerFileContainers({newerContainer}); - - ASSERT_THAT(newerFileContainers.size(), 1); -} - -TEST_F(Documents, ThrowForRemovingWithWrongFilePath) -{ - ClangBackEnd::FileContainer fileContainer(nonExistingFilePath); - - ASSERT_THROW(documents.remove({fileContainer}), - ClangBackEnd::DocumentDoesNotExistException); -} - -TEST_F(Documents, Remove) -{ - ClangBackEnd::FileContainer fileContainer(filePath); - documents.create({fileContainer}); - - documents.remove({fileContainer}); - - ASSERT_THROW(documents.document(filePath), - ClangBackEnd::DocumentDoesNotExistException); -} - -TEST_F(Documents, RemoveAllValidIfExceptionIsThrown) -{ - ClangBackEnd::FileContainer fileContainer(filePath); - documents.create({fileContainer}); - - ASSERT_THROW(documents.remove({ClangBackEnd::FileContainer(Utf8StringLiteral("dontextist.pro")), fileContainer}), - ClangBackEnd::DocumentDoesNotExistException); - - ASSERT_THAT(documents.documents(), - Not(Contains(Document(filePath, {}, {}, documents)))); -} - -TEST_F(Documents, HasDocument) -{ - documents.create({{filePath}}); - - ASSERT_TRUE(documents.hasDocument(filePath)); -} - -TEST_F(Documents, HasNotDocument) -{ - ASSERT_FALSE(documents.hasDocument(filePath)); -} - -TEST_F(Documents, FilteredPositive) -{ - documents.create({{filePath}}); - const auto isMatchingFilePath = [this](const Document &document) { - return document.filePath() == filePath; - }; - - const bool hasMatches = !documents.filtered(isMatchingFilePath).empty(); - - ASSERT_TRUE(hasMatches); -} - -TEST_F(Documents, FilteredNegative) -{ - documents.create({{filePath}}); - const auto isMatchingNothing = [](const Document &) { - return false; - }; - - const bool hasMatches = !documents.filtered(isMatchingNothing).empty(); - - ASSERT_FALSE(hasMatches); -} - -TEST_F(Documents, DirtyAndVisibleButNotCurrentDocuments) -{ - documents.create({{filePath}}); - documents.updateDocumentsWithChangedDependency(filePath); - documents.setVisibleInEditors({filePath}); - documents.setUsedByCurrentEditor(Utf8String()); - - const bool hasMatches = !documents.dirtyAndVisibleButNotCurrentDocuments().empty(); - - ASSERT_TRUE(hasMatches); -} - -TEST_F(Documents, isUsedByCurrentEditor) -{ - documents.create({fileContainer}); - auto document = documents.document(fileContainer); - - documents.setUsedByCurrentEditor(filePath); - - ASSERT_TRUE(document.isUsedByCurrentEditor()); -} - -TEST_F(Documents, IsNotCurrentEditor) -{ - documents.create({fileContainer}); - auto document = documents.document(fileContainer); - - documents.setUsedByCurrentEditor(headerPath); - - ASSERT_FALSE(document.isUsedByCurrentEditor()); -} - -TEST_F(Documents, IsNotCurrentEditorAfterBeingCurrent) -{ - documents.create({fileContainer}); - auto document = documents.document(fileContainer); - documents.setUsedByCurrentEditor(filePath); - - documents.setUsedByCurrentEditor(headerPath); - - ASSERT_FALSE(document.isUsedByCurrentEditor()); -} - -TEST_F(Documents, IsVisibleEditor) -{ - documents.create({fileContainer}); - auto document = documents.document(fileContainer); - - documents.setVisibleInEditors({filePath}); - - ASSERT_TRUE(document.isVisibleInEditor()); -} - -TEST_F(Documents, IsNotVisibleEditor) -{ - documents.create({fileContainer}); - auto document = documents.document(fileContainer); - - documents.setVisibleInEditors({headerPath}); - - ASSERT_FALSE(document.isVisibleInEditor()); -} - -TEST_F(Documents, IsNotVisibleEditorAfterBeingVisible) -{ - documents.create({fileContainer}); - auto document = documents.document(fileContainer); - documents.setVisibleInEditors({filePath}); - - documents.setVisibleInEditors({headerPath}); - - ASSERT_FALSE(document.isVisibleInEditor()); -} - -// TODO: Remove? -void Documents::SetUp() -{ -} - -} diff --git a/tests/unit/unittest/clangdocumentsuspenderresumer-test.cpp b/tests/unit/unittest/clangdocumentsuspenderresumer-test.cpp deleted file mode 100644 index 569f7d6355..0000000000 --- a/tests/unit/unittest/clangdocumentsuspenderresumer-test.cpp +++ /dev/null @@ -1,311 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include "dummyclangipcclient.h" - -#include <clangclock.h> -#include <clangdocument.h> -#include <clangdocumentprocessors.h> -#include <clangdocuments.h> -#include <clangdocumentsuspenderresumer.h> -#include <clangtranslationunits.h> -#include <unsavedfiles.h> -#include <utf8string.h> - -#include <utils/algorithm.h> - -#include <clang-c/Index.h> - -using ClangBackEnd::Clock; -using ClangBackEnd::Document; -using ClangBackEnd::JobRequest; -using ClangBackEnd::PreferredTranslationUnit; -using ClangBackEnd::SuspendResumeJobs; -using ClangBackEnd::SuspendResumeJobsEntry; -using ClangBackEnd::TimePoint; - -using testing::ContainerEq; -using testing::ElementsAre; -using testing::IsEmpty; - -namespace ClangBackEnd { - -bool operator==(const SuspendResumeJobsEntry &a, const SuspendResumeJobsEntry &b) -{ - return a.document == b.document - && a.jobRequestType == b.jobRequestType - && a.preferredTranslationUnit == b.preferredTranslationUnit; -} - -} // ClangBackEnd - -namespace { - -class DocumentSuspenderResumer : public ::testing::Test -{ -protected: - Document getDocument(const Utf8String &filePath); - void categorizeDocuments(int hotDocumentsSize); - SuspendResumeJobs createSuspendResumeJobs(int hotDocumentsSize = -1); - static void setParsed(Document &document); - -protected: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - DummyIpcClient dummyIpcClient; - ClangBackEnd::DocumentProcessors documentProcessors{documents, unsavedFiles, dummyIpcClient}; - - const Utf8String filePath1 = Utf8StringLiteral(TESTDATA_DIR"/empty1.cpp"); - const ClangBackEnd::FileContainer fileContainer1{filePath1, Utf8String(), true}; - - const Utf8String filePath2 = Utf8StringLiteral(TESTDATA_DIR"/empty2.cpp"); - const ClangBackEnd::FileContainer fileContainer2{filePath2, Utf8String(), true}; - - const Utf8String filePath3 = Utf8StringLiteral(TESTDATA_DIR"/empty3.cpp"); - const ClangBackEnd::FileContainer fileContainer3{filePath3, Utf8String(), true}; - - std::vector<Document> hotDocuments; - std::vector<Document> coldDocuments; -}; - -TEST_F(DocumentSuspenderResumer, CategorizeNoDocuments) -{ - categorizeDocuments(99); - - ASSERT_THAT(hotDocuments, IsEmpty()); - ASSERT_THAT(coldDocuments, IsEmpty()); -} - -TEST_F(DocumentSuspenderResumer, CategorizeSingleDocument) -{ - documents.create({fileContainer1}); - - categorizeDocuments(99); - - ASSERT_THAT(hotDocuments, ElementsAre(getDocument(filePath1))); - ASSERT_THAT(coldDocuments, IsEmpty()); -} - -TEST_F(DocumentSuspenderResumer, CategorizeKeepsStableOrder) -{ - documents.create({fileContainer1, fileContainer2}); - - categorizeDocuments(99); - - ASSERT_THAT(hotDocuments, ElementsAre(getDocument(filePath1), - getDocument(filePath2))); -} - -TEST_F(DocumentSuspenderResumer, CategorizePutsLastVisibleToTopOfHotDocuments) -{ - documents.create({fileContainer1, fileContainer2}); - documents.setVisibleInEditors({filePath1}); - documents.setVisibleInEditors({filePath2}); - - categorizeDocuments(99); - - ASSERT_THAT(hotDocuments, ElementsAre(getDocument(filePath2), - getDocument(filePath1))); -} - -TEST_F(DocumentSuspenderResumer, CategorizeWithLessDocumentsThanWeCareFor) -{ - documents.create({fileContainer1}); - - categorizeDocuments(2); - - ASSERT_THAT(hotDocuments, ElementsAre(getDocument(filePath1))); - ASSERT_THAT(coldDocuments, IsEmpty()); -} - -TEST_F(DocumentSuspenderResumer, CategorizeWithZeroHotDocuments) -{ - documents.create({fileContainer1}); - - categorizeDocuments(0); - - ASSERT_THAT(hotDocuments, IsEmpty()); - ASSERT_THAT(coldDocuments, ElementsAre(getDocument(filePath1))); -} - -TEST_F(DocumentSuspenderResumer, CategorizeWithMoreVisibleDocumentsThanHotDocuments) -{ - const TimePoint timePoint = Clock::now(); - Document document1 = documents.create({fileContainer1})[0]; - document1.setIsVisibleInEditor(true, timePoint); - Document document2 = documents.create({fileContainer2})[0]; - document2.setIsVisibleInEditor(true, timePoint); - - categorizeDocuments(1); - - ASSERT_THAT(hotDocuments, ElementsAre(getDocument(filePath1), getDocument(filePath2))); - ASSERT_THAT(coldDocuments, IsEmpty()); -} - -TEST_F(DocumentSuspenderResumer, CreateSuspendJobForInvisible) -{ - Document document = documents.create({fileContainer1})[0]; - document.setIsSuspended(false); - document.setIsVisibleInEditor(false, Clock::now()); - setParsed(document); - - const SuspendResumeJobs expectedJobs = { - {document, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::RecentlyParsed} - }; - - const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 0); - - ASSERT_THAT(jobs, ContainerEq(expectedJobs)); -} - -TEST_F(DocumentSuspenderResumer, DoNotCreateSuspendJobForVisible) -{ - Document document = documents.create({fileContainer1})[0]; - document.setIsSuspended(false); - document.setIsVisibleInEditor(true, Clock::now()); - - const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 0); - - ASSERT_THAT(jobs, IsEmpty()); -} - -TEST_F(DocumentSuspenderResumer, DoNotCreateSuspendJobForUnparsed) -{ - Document document = documents.create({fileContainer1})[0]; - document.setIsSuspended(false); - document.setIsVisibleInEditor(true, Clock::now()); - - const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 0); - - ASSERT_THAT(jobs, IsEmpty()); -} - -TEST_F(DocumentSuspenderResumer, CreateSuspendJobsForDocumentWithSupportiveTranslationUnit) -{ - Document document = documents.create({fileContainer1})[0]; - document.setIsSuspended(false); - document.setIsVisibleInEditor(false, Clock::now()); - document.translationUnits().createAndAppend(); // Add supportive translation unit - setParsed(document); - const SuspendResumeJobs expectedJobs = { - {document, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::RecentlyParsed}, - {document, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::PreviouslyParsed}, - }; - - const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 0); - - ASSERT_THAT(jobs, ContainerEq(expectedJobs)); -} - -TEST_F(DocumentSuspenderResumer, CreateResumeJob) -{ - Document document = documents.create({fileContainer1})[0]; - document.setIsSuspended(true); - document.setIsVisibleInEditor(true, Clock::now()); - const SuspendResumeJobs expectedJobs = { - {document, JobRequest::Type::ResumeDocument, PreferredTranslationUnit::RecentlyParsed} - }; - - const SuspendResumeJobs jobs = createSuspendResumeJobs(); - - ASSERT_THAT(jobs, ContainerEq(expectedJobs)); -} - -TEST_F(DocumentSuspenderResumer, DoNotCreateResumeJobForInvisible) -{ - Document document = documents.create({fileContainer1})[0]; - document.setIsSuspended(true); - document.setIsVisibleInEditor(false, Clock::now()); - - const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 0); - - ASSERT_THAT(jobs, IsEmpty()); -} - -TEST_F(DocumentSuspenderResumer, CreateResumeJobsForDocumentWithSupportiveTranslationUnit) -{ - Document document = documents.create({fileContainer1})[0]; - document.setIsSuspended(true); - document.setIsVisibleInEditor(true, Clock::now()); - document.translationUnits().createAndAppend(); // Add supportive translation unit - const SuspendResumeJobs expectedJobs = { - {document, JobRequest::Type::ResumeDocument, PreferredTranslationUnit::RecentlyParsed}, - {document, JobRequest::Type::ResumeDocument, PreferredTranslationUnit::PreviouslyParsed}, - }; - - const SuspendResumeJobs jobs = createSuspendResumeJobs(); - - ASSERT_THAT(jobs, ContainerEq(expectedJobs)); -} - -TEST_F(DocumentSuspenderResumer, CreateSuspendAndResumeJobs) -{ - Document hotDocument = documents.create({fileContainer1})[0]; - hotDocument.setIsSuspended(true); - Document coldDocument = documents.create({fileContainer2})[0]; - setParsed(coldDocument); - coldDocument.setIsSuspended(false); - documents.setVisibleInEditors({filePath1}); - const SuspendResumeJobs expectedJobs = { - {coldDocument, JobRequest::Type::SuspendDocument, PreferredTranslationUnit::RecentlyParsed}, - {hotDocument, JobRequest::Type::ResumeDocument, PreferredTranslationUnit::RecentlyParsed}, - }; - - const SuspendResumeJobs jobs = createSuspendResumeJobs(/*hotDocumentsSize=*/ 1); - - ASSERT_THAT(jobs, ContainerEq(expectedJobs)); -} - -ClangBackEnd::Document DocumentSuspenderResumer::getDocument(const Utf8String &filePath) -{ - return documents.document(filePath); -} - -void DocumentSuspenderResumer::categorizeDocuments(int hotDocumentsSize) -{ - categorizeHotColdDocuments(hotDocumentsSize, documents.documents(), hotDocuments, - coldDocuments); -} - -ClangBackEnd::SuspendResumeJobs -DocumentSuspenderResumer::createSuspendResumeJobs(int hotDocumentsSize) -{ - return ClangBackEnd::createSuspendResumeJobs(documents.documents(), hotDocumentsSize); -} - -void DocumentSuspenderResumer::setParsed(ClangBackEnd::Document &document) -{ - const Utf8String first = document.translationUnit().id(); - document.translationUnits().updateParseTimePoint(first, Clock::now()); - - const Utf8String second - = document.translationUnit(PreferredTranslationUnit::LastUninitialized).id(); - if (second != first) - document.translationUnits().updateParseTimePoint(second, Clock::now()); -} - -} // anonymous diff --git a/tests/unit/unittest/clangfollowsymbol-test.cpp b/tests/unit/unittest/clangfollowsymbol-test.cpp deleted file mode 100644 index 29c0a702b3..0000000000 --- a/tests/unit/unittest/clangfollowsymbol-test.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "unittest-utility-functions.h" - -#include <clangsupport_global.h> -#include <clangfollowsymboljob.h> -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangtranslationunit.h> -#include <fixitcontainer.h> -#include <followsymbolmessage.h> -#include <sourcelocationcontainer.h> -#include <sourcerangecontainer.h> -#include <unsavedfiles.h> -#include <commandlinearguments.h> - -#include <utils/qtcassert.h> - -#include <clang-c/Index.h> - -using ::testing::Contains; -using ::testing::Not; -using ::testing::ContainerEq; -using ::testing::Eq; -using ::testing::PrintToString; - -using ::ClangBackEnd::SourceLocationContainer; -using ::ClangBackEnd::Document; -using ::ClangBackEnd::UnsavedFiles; -using ::ClangBackEnd::ReferencesResult; -using ::ClangBackEnd::SourceRangeContainer; -using ::ClangBackEnd::FollowSymbolResult; - -namespace { -const Utf8String sourceFilePath = Utf8StringLiteral(TESTDATA_DIR"/followsymbol_main.cpp"); -const Utf8String headerFilePath = Utf8StringLiteral(TESTDATA_DIR"/followsymbol_header.h"); -const Utf8String cursorPath = Utf8StringLiteral(TESTDATA_DIR"/cursor.cpp"); - -MATCHER_P3(MatchesHeaderSourceRange, line, column, length, - std::string(negation ? "isn't " : "is ") - + PrintToString(SourceRangeContainer { - SourceLocationContainer(headerFilePath, line, column), - SourceLocationContainer(headerFilePath, line, column + length) - }) - ) -{ - const SourceRangeContainer expected = { - SourceLocationContainer(headerFilePath, line, column), - SourceLocationContainer(headerFilePath, line, column + length) - }; - - return arg == expected; -} - -MATCHER_P3(MatchesSourceRange, line, column, length, - std::string(negation ? "isn't " : "is ") - + PrintToString(SourceRangeContainer { - SourceLocationContainer(sourceFilePath, line, column), - SourceLocationContainer(sourceFilePath, line, column + length) - }) - ) -{ - const SourceRangeContainer expected = { - SourceLocationContainer(sourceFilePath, line, column), - SourceLocationContainer(sourceFilePath, line, column + length) - }; - - return arg == expected; -} - -MATCHER_P4(MatchesFileSourceRange, filename, line, column, length, - std::string(negation ? "isn't " : "is ") - + PrintToString(SourceRangeContainer { - SourceLocationContainer(filename, line, column), - SourceLocationContainer(filename, line, column + length) - }) - ) -{ - const SourceRangeContainer expected = { - SourceLocationContainer(filename, line, column), - SourceLocationContainer(filename, line, column + length) - }; - - return arg == expected; -} - -class Data { -public: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Utf8StringVector compilationArguments{ - UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++14")})}; - Document document = {sourceFilePath, compilationArguments, {}, documents}; - Document headerDocument = {headerFilePath, compilationArguments, {}, documents}; - QVector<Utf8String> deps{sourceFilePath, cursorPath}; -}; - -class FollowSymbol : public ::testing::Test -{ -protected: - FollowSymbolResult followSymbol(uint line, uint column) - { - return document.translationUnit().followSymbol(line, column); - } - - FollowSymbolResult followHeaderSymbol(uint line, uint column) - { - return headerDocument.translationUnit().followSymbol(line, column); - } - - static void SetUpTestCase(); - static void TearDownTestCase(); - -private: - static std::unique_ptr<const Data> data; - const Document &document{data->document}; - const Document &headerDocument{data->headerDocument}; - const QVector<Utf8String> &deps{data->deps}; -}; - -// NOTE: some tests are disabled because clang code model does not need to follow symbols -// to other translation units. When there's infrastructure to test database based follow symbol -// they should be moved there. - -TEST_F(FollowSymbol, CursorOnNamespace) -{ - const auto namespaceDefinition = followSymbol(27, 1); - - ASSERT_THAT(namespaceDefinition, MatchesHeaderSourceRange(28, 11, 6)); -} - -TEST_F(FollowSymbol, CursorOnClassReference) -{ - const auto classDefinition = followSymbol(27, 9); - - ASSERT_THAT(classDefinition, MatchesHeaderSourceRange(34, 7, 3)); -} - -TEST_F(FollowSymbol, CursorOnClassForwardDeclarationFollowToHeader) -{ - const auto classDefinition = followHeaderSymbol(32, 7); - - ASSERT_THAT(classDefinition, MatchesHeaderSourceRange(34, 7, 3)); -} - -TEST_F(FollowSymbol, DISABLED_CursorOnClassForwardDeclarationFollowToCpp) -{ - const auto classDefinition = followHeaderSymbol(48, 9); - - ASSERT_THAT(classDefinition, MatchesSourceRange(54, 7, 8)); -} - -TEST_F(FollowSymbol, CursorOnClassDefinition) -{ - const auto classForwardDeclaration = followHeaderSymbol(34, 7); - - ASSERT_THAT(classForwardDeclaration, MatchesHeaderSourceRange(32, 7, 3)); -} - -TEST_F(FollowSymbol, CursorOnClassDefinitionInCpp) -{ - const auto classForwardDeclaration = followSymbol(54, 7); - - ASSERT_THAT(classForwardDeclaration, MatchesHeaderSourceRange(48, 7, 8)); -} - -TEST_F(FollowSymbol, DISABLED_CursorOnConstructorDeclaration) -{ - const auto constructorDefinition = followHeaderSymbol(36, 5); - - ASSERT_THAT(constructorDefinition, MatchesSourceRange(27, 14, 3)); -} - -TEST_F(FollowSymbol, CursorOnConstructorDefinition) -{ - const auto constructorDeclaration = followSymbol(27, 14); - - ASSERT_THAT(constructorDeclaration, MatchesHeaderSourceRange(36, 5, 3)); -} - -TEST_F(FollowSymbol, CursorOnMemberReference) -{ - const auto memberDeclaration = followSymbol(39, 10); - - ASSERT_THAT(memberDeclaration, MatchesHeaderSourceRange(38, 18, 6)); -} - -TEST_F(FollowSymbol, CursorOnMemberReferenceAnonymousUnion) -{ - const auto memberDeclaration = followSymbol(91, 20); - - ASSERT_THAT(memberDeclaration, MatchesSourceRange(86, 13, 1)); -} - -TEST_F(FollowSymbol, CursorOnMemberDeclaration) -{ - const auto sameMemberDeclaration = followHeaderSymbol(38, 18); - - ASSERT_THAT(sameMemberDeclaration, MatchesHeaderSourceRange(38, 18, 6)); -} - -TEST_F(FollowSymbol, CursorOnFunctionReference) -{ - const auto functionDefinition = followSymbol(66, 12); - - ASSERT_THAT(functionDefinition, MatchesSourceRange(35, 5, 3)); -} - -TEST_F(FollowSymbol, DISABLED_CursorOnMemberFunctionReference) -{ - const auto memberFunctionDefinition = followSymbol(42, 12); - - ASSERT_THAT(memberFunctionDefinition, MatchesSourceRange(49, 21, 3)); -} - -TEST_F(FollowSymbol, DISABLED_CursorOnFunctionWithoutDefinitionReference) -{ - const auto functionDeclaration = followSymbol(43, 5); - - ASSERT_THAT(functionDeclaration, MatchesHeaderSourceRange(59, 5, 3)); -} - -TEST_F(FollowSymbol, CursorOnFunctionDefinition) -{ - const auto functionDeclaration = followSymbol(35, 5); - - ASSERT_THAT(functionDeclaration, MatchesHeaderSourceRange(52, 5, 3)); -} - -TEST_F(FollowSymbol, CursorOnMemberFunctionDefinition) -{ - const auto memberFunctionDeclaration = followSymbol(49, 21); - - ASSERT_THAT(memberFunctionDeclaration, MatchesHeaderSourceRange(43, 9, 3)); -} - -TEST_F(FollowSymbol, DISABLED_CursorOnMemberFunctionDeclaration) -{ - const auto memberFunctionDefinition = followHeaderSymbol(43, 9); - - ASSERT_THAT(memberFunctionDefinition, MatchesSourceRange(49, 21, 3)); -} - -TEST_F(FollowSymbol, CursorOnInclude) -{ - const auto startOfIncludeFile = followSymbol(25, 13); - - ASSERT_THAT(startOfIncludeFile, MatchesHeaderSourceRange(1, 1, 0)); -} - -TEST_F(FollowSymbol, CursorOnLocalVariable) -{ - const auto variableDeclaration = followSymbol(39, 6); - - ASSERT_THAT(variableDeclaration, MatchesSourceRange(36, 9, 3)); -} - -TEST_F(FollowSymbol, CursorOnClassAlias) -{ - const auto aliasDefinition = followSymbol(36, 5); - - ASSERT_THAT(aliasDefinition, MatchesSourceRange(33, 7, 3)); -} - -TEST_F(FollowSymbol, CursorOnStaticVariable) -{ - const auto staticVariableDeclaration = followSymbol(40, 27); - - ASSERT_THAT(staticVariableDeclaration, MatchesHeaderSourceRange(30, 7, 7)); -} - -TEST_F(FollowSymbol, DISABLED_CursorOnFunctionFromOtherClass) -{ - const auto functionDefinition = followSymbol(62, 39); - - ASSERT_THAT(functionDefinition, MatchesFileSourceRange(cursorPath, 104, 22, 8)); -} - -TEST_F(FollowSymbol, DISABLED_CursorOnDefineReference) -{ - const auto functionDefinition = followSymbol(66, 43); - - ASSERT_THAT(functionDefinition, MatchesHeaderSourceRange(27, 9, 11)); -} - - -TEST_F(FollowSymbol, CursorInTheMiddleOfNamespace) -{ - const auto namespaceDefinition = followSymbol(27, 3); - - ASSERT_THAT(namespaceDefinition, MatchesHeaderSourceRange(28, 11, 6)); -} - -TEST_F(FollowSymbol, CursorAfterNamespace) -{ - const auto namespaceDefinition = followSymbol(27, 7); - - ASSERT_THAT(namespaceDefinition, MatchesFileSourceRange(QString(""), 0, 0, 0)); -} - -TEST_F(FollowSymbol, CursorOnOneSymbolOperatorDefinition) -{ - const auto namespaceDefinition = followSymbol(76, 13); - - ASSERT_THAT(namespaceDefinition, MatchesSourceRange(72, 9, 9)); -} - -TEST_F(FollowSymbol, CursorOnTwoSymbolOperatorDefinition) -{ - const auto namespaceDefinition = followSymbol(80, 15); - - ASSERT_THAT(namespaceDefinition, MatchesSourceRange(73, 10, 10)); -} - -TEST_F(FollowSymbol, CursorOnOneSymbolOperatorDeclaration) -{ - const auto namespaceDefinition = followSymbol(72, 12); - - ASSERT_THAT(namespaceDefinition, MatchesSourceRange(76, 10, 9)); -} - -TEST_F(FollowSymbol, CursorOnTwoSymbolOperatorDeclaration) -{ - const auto namespaceDefinition = followSymbol(73, 12); - - ASSERT_THAT(namespaceDefinition, MatchesSourceRange(80, 11, 10)); -} - -std::unique_ptr<const Data> FollowSymbol::data; - -void FollowSymbol::SetUpTestCase() -{ - data = std::make_unique<Data>(); - data->document.parse(); - data->headerDocument.parse(); -} - -void FollowSymbol::TearDownTestCase() -{ - data.reset(); -} - -} // anonymous namespace diff --git a/tests/unit/unittest/clangjobqueue-test.cpp b/tests/unit/unittest/clangjobqueue-test.cpp deleted file mode 100644 index 8e00dccd2f..0000000000 --- a/tests/unit/unittest/clangjobqueue-test.cpp +++ /dev/null @@ -1,512 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "processevents-utilities.h" - -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangtranslationunit.h> -#include <clangtranslationunits.h> -#include <clangjobs.h> -#include <filecontainer.h> -#include <unsavedfiles.h> - -#include <clang-c/Index.h> - -#include <QTemporaryFile> - -using namespace ClangBackEnd; - -using testing::IsNull; -using testing::NotNull; -using testing::Eq; -using testing::Gt; -using testing::Contains; -using testing::EndsWith; -using testing::AllOf; - -namespace { - -class JobQueue : public ::testing::Test -{ -protected: - void SetUp() override; - - void resetVisibilityAndCurrentEditor(); - - Utf8String createTranslationUnitForDeletedFile(); - - JobRequest createJobRequest(const Utf8String &filePath, - JobRequest::Type type, - PreferredTranslationUnit preferredTranslationUnit - = PreferredTranslationUnit::RecentlyParsed) const; - - void pretendParsedTranslationUnit(); - - void updateDocumentRevision(); - void updateUnsavedFiles(); - void removeDocument(); - -protected: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - ClangBackEnd::Document document; - - Utf8String filePath1 = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp"); - Utf8String filePath2 = Utf8StringLiteral(TESTDATA_DIR"/skippedsourceranges.cpp"); - - ClangBackEnd::JobQueue jobQueue{documents}; -}; - -TEST_F(JobQueue, AddJob) -{ - const JobRequest jobRequest = createJobRequest(filePath1, - JobRequest::Type::UpdateAnnotations); - - jobQueue.add(jobRequest); - - ASSERT_THAT(jobQueue.queue().size(), Eq(1)); -} - -TEST_F(JobQueue, DoNotAddDuplicate) -{ - const JobRequest request = createJobRequest(filePath1, - JobRequest::Type::UpdateAnnotations); - jobQueue.add(request); - - const bool added = jobQueue.add(request); - - ASSERT_FALSE(added); -} - -TEST_F(JobQueue, DoNotAddDuplicateForWhichAJobIsAlreadyRunning) -{ - jobQueue.setIsJobRunningForJobRequestHandler([](const JobRequest &) { - return true; - }); - - const bool added = jobQueue.add(createJobRequest(filePath1, - JobRequest::Type::UpdateAnnotations)); - - ASSERT_FALSE(added); -} - -TEST_F(JobQueue, DoNotAddForNotExistingDocument) -{ - jobQueue.setCancelJobRequest([](const JobRequest &) { - return true; - }); - - const bool added = jobQueue.add(createJobRequest(Utf8StringLiteral("notExistingDocument.cpp"), - JobRequest::Type::UpdateAnnotations)); - - ASSERT_FALSE(added); -} - -TEST_F(JobQueue, DoNotAddForNotIntactDocument) -{ - document.setHasParseOrReparseFailed(true); - const bool added = jobQueue.add(createJobRequest(filePath1, - JobRequest::Type::UpdateAnnotations)); - - ASSERT_FALSE(added); -} - -TEST_F(JobQueue, CancelDuringAddForNotIntactDocument) -{ - document.setHasParseOrReparseFailed(true); - bool canceled = false; - jobQueue.setCancelJobRequest([&canceled](const JobRequest &) { - canceled = true; - }); - - - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - - ASSERT_TRUE(canceled); -} - -TEST_F(JobQueue, ProcessEmpty) -{ - jobQueue.processQueue(); - - ASSERT_THAT(jobQueue.size(), Eq(0)); -} - -TEST_F(JobQueue, ProcessSingleJob) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - - const JobRequests jobsToRun = jobQueue.processQueue(); - - ASSERT_THAT(jobsToRun.size(), Eq(1)); - ASSERT_THAT(jobQueue.size(), Eq(0)); -} - -TEST_F(JobQueue, ProcessUntilEmpty) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::ParseSupportiveTranslationUnit)); - - JobRequests jobsToRun; - ASSERT_THAT(jobQueue.size(), Eq(2)); - - jobsToRun = jobQueue.processQueue(); - ASSERT_THAT(jobQueue.size(), Eq(1)); - ASSERT_THAT(jobsToRun.size(), Eq(1)); - - jobsToRun = jobQueue.processQueue(); - ASSERT_THAT(jobQueue.size(), Eq(0)); - ASSERT_THAT(jobsToRun.size(), Eq(1)); -} - -TEST_F(JobQueue, RemoveRequestsForClosedDocuments) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - removeDocument(); - - const JobRequests jobsToRun = jobQueue.processQueue(); - - ASSERT_THAT(jobQueue.size(), Eq(0)); - ASSERT_THAT(jobsToRun.size(), Eq(0)); -} - -TEST_F(JobQueue, RemoveRequestsForOudatedUnsavedFiles) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - updateUnsavedFiles(); - - const JobRequests jobsToRun = jobQueue.processQueue(); - - ASSERT_THAT(jobQueue.size(), Eq(0)); - ASSERT_THAT(jobsToRun.size(), Eq(0)); -} - -TEST_F(JobQueue, RemoveRequestsForChangedDocumentRevision) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - updateDocumentRevision(); - - const JobRequests jobsToRun = jobQueue.processQueue(); - - ASSERT_THAT(jobQueue.size(), Eq(0)); - ASSERT_THAT(jobsToRun.size(), Eq(0)); -} - -TEST_F(JobQueue, RemoveRequestsForNotIntactDocuments) -{ - const Utf8String filePath = createTranslationUnitForDeletedFile(); - jobQueue.add(createJobRequest(filePath, JobRequest::Type::UpdateAnnotations)); - - const JobRequests jobsToRun = jobQueue.processQueue(); - - ASSERT_THAT(jobQueue.size(), Eq(0)); - ASSERT_THAT(jobsToRun.size(), Eq(0)); -} - -TEST_F(JobQueue, CancelRequestsForNotIntactDocuments) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - document.setHasParseOrReparseFailed(true); - bool canceled = false; - jobQueue.setCancelJobRequest([&canceled](const JobRequest &) { - canceled = true; - }); - - jobQueue.processQueue(); - - ASSERT_TRUE(canceled); -} - -TEST_F(JobQueue, PrioritizeCurrentDocumentOverNotCurrent) -{ - resetVisibilityAndCurrentEditor(); - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - jobQueue.add(createJobRequest(filePath2, JobRequest::Type::UpdateAnnotations)); - documents.setUsedByCurrentEditor(filePath2); - - jobQueue.prioritizeRequests(); - - ASSERT_THAT(jobQueue.queue().first().filePath, Eq(filePath2)); -} - -TEST_F(JobQueue, PrioritizeVisibleDocumentsOverNotVisible) -{ - resetVisibilityAndCurrentEditor(); - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - jobQueue.add(createJobRequest(filePath2, JobRequest::Type::UpdateAnnotations)); - documents.setVisibleInEditors({filePath2}); - - jobQueue.prioritizeRequests(); - - ASSERT_THAT(jobQueue.queue().first().filePath, Eq(filePath2)); -} - -TEST_F(JobQueue, PrioritizeCurrentDocumentOverVisible) -{ - resetVisibilityAndCurrentEditor(); - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - jobQueue.add(createJobRequest(filePath2, JobRequest::Type::UpdateAnnotations)); - documents.setVisibleInEditors({filePath1, filePath2}); - documents.setUsedByCurrentEditor(filePath2); - - jobQueue.prioritizeRequests(); - - ASSERT_THAT(jobQueue.queue().first().filePath, Eq(filePath2)); -} - -TEST_F(JobQueue, RunNothingForNotCurrentOrVisibleDocument) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - documents.setVisibleInEditors({}); - documents.setUsedByCurrentEditor(Utf8StringLiteral("aNonExistingFilePath")); - - const JobRequests jobsToRun = jobQueue.processQueue(); - - ASSERT_THAT(jobsToRun.size(), Eq(0)); -} - -TEST_F(JobQueue, RunOnlyOneJobPerTranslationUnitIfMultipleAreInQueue) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestAnnotations)); - - const JobRequests jobsToRun = jobQueue.processQueue(); - - ASSERT_THAT(jobsToRun.size(), Eq(1)); - ASSERT_THAT(jobQueue.size(), Eq(1)); -} - -TEST_F(JobQueue, RunJobsForDistinctTranslationUnits) -{ - const TranslationUnit initialTu = document.translationUnit(); - document.translationUnits().updateParseTimePoint(initialTu.id(), Clock::now()); - const TranslationUnit alternativeTu = document.translationUnits().createAndAppend(); - document.translationUnits().updateParseTimePoint(alternativeTu.id(), Clock::now()); - jobQueue.add(createJobRequest(filePath1, - JobRequest::Type::UpdateAnnotations, - PreferredTranslationUnit::RecentlyParsed)); - jobQueue.add(createJobRequest(filePath1, - JobRequest::Type::UpdateAnnotations, - PreferredTranslationUnit::PreviouslyParsed)); - - const JobRequests jobsToRun = jobQueue.processQueue(); - - ASSERT_THAT(jobsToRun.size(), Eq(2)); - ASSERT_THAT(jobQueue.size(), Eq(0)); -} -TEST_F(JobQueue, DoNotRunJobForTranslationUnittThatIsBeingProcessed) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - JobRequests jobsToRun = jobQueue.processQueue(); - jobQueue.setIsJobRunningForTranslationUnitHandler([](const Utf8String &) { - return true; - }); - - jobsToRun = jobQueue.processQueue(); - - ASSERT_THAT(jobsToRun.size(), Eq(0)); -} - -TEST_F(JobQueue, RequestUpdateAnnotationsOutdatableByUnsavedFileChange) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - updateUnsavedFiles(); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(0)); -} - -TEST_F(JobQueue, RequestUpdateAnnotationsOutdatableByDocumentClose) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - removeDocument(); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(0)); -} - -TEST_F(JobQueue, RequestUpdateAnnotationsOutdatableByNotIntactDocument) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::UpdateAnnotations)); - document.setHasParseOrReparseFailed(true); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(0)); -} - -TEST_F(JobQueue, RequestCompleteCodeOutdatableByDocumentClose) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestCompletions)); - removeDocument(); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(0)); -} - -TEST_F(JobQueue, RequestCompleteCodeNotOutdatableByUnsavedFilesChange) -{ - pretendParsedTranslationUnit(); - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestCompletions)); - updateUnsavedFiles(); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(1)); -} - -TEST_F(JobQueue, RequestCompleteCodeNotOutdatableByDocumentRevisionChange) -{ - pretendParsedTranslationUnit(); - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestCompletions)); - updateDocumentRevision(); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(1)); -} - -TEST_F(JobQueue, RequestCompleteCodeOutdatableByDocumentRevisionChange) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestAnnotations)); - updateDocumentRevision(); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(0)); -} - -TEST_F(JobQueue, RequestReferencesRunsForCurrentDocumentRevision) -{ - pretendParsedTranslationUnit(); - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestReferences)); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(1)); -} - -TEST_F(JobQueue, RequestReferencesOutdatableByDocumentClose) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestReferences)); - removeDocument(); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(0)); - ASSERT_THAT(jobQueue.size(), Eq(0)); -} - -TEST_F(JobQueue, RequestReferencesDoesNotRunOnSuspendedDocument) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::RequestReferences)); - document.setIsSuspended(true); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(0)); - ASSERT_THAT(jobQueue.size(), Eq(1)); -} - -TEST_F(JobQueue, ResumeDocumentDoesNotRunOnUnsuspended) -{ - jobQueue.add(createJobRequest(filePath1, JobRequest::Type::ResumeDocument)); - document.setIsSuspended(false); - - const JobRequests jobsToStart = jobQueue.processQueue(); - - ASSERT_THAT(jobsToStart.size(), Eq(0)); - ASSERT_THAT(jobQueue.size(), Eq(1)); -} - -void JobQueue::SetUp() -{ - const QVector<FileContainer> fileContainer{FileContainer(filePath1), - FileContainer(filePath2)}; - document = documents.create(fileContainer).front(); - documents.setVisibleInEditors({filePath1}); - documents.setUsedByCurrentEditor(filePath1); -} - -void JobQueue::resetVisibilityAndCurrentEditor() -{ - documents.setVisibleInEditors({}); - documents.setUsedByCurrentEditor(Utf8String()); -} - -Utf8String JobQueue::createTranslationUnitForDeletedFile() -{ - QTemporaryFile temporaryFile(QLatin1String("XXXXXX.cpp")); - EXPECT_TRUE(temporaryFile.open()); - const QString temporaryFilePath = Utf8String::fromString(temporaryFile.fileName()); - - ClangBackEnd::FileContainer fileContainer(temporaryFilePath, Utf8String(), true); - documents.create({fileContainer}); - auto document = documents.document(fileContainer); - document.setIsUsedByCurrentEditor(true); - - return temporaryFilePath; -} - -JobRequest JobQueue::createJobRequest( - const Utf8String &filePath, - JobRequest::Type type, - PreferredTranslationUnit preferredTranslationUnit) const -{ - JobRequest jobRequest(type); - jobRequest.filePath = filePath; - jobRequest.unsavedFilesChangeTimePoint = unsavedFiles.lastChangeTimePoint(); - jobRequest.documentRevision = document.documentRevision(); - jobRequest.preferredTranslationUnit = preferredTranslationUnit; - - return jobRequest; -} - -void JobQueue::pretendParsedTranslationUnit() -{ - document.translationUnits().updateParseTimePoint(document.translationUnit().id(), Clock::now()); -} - -void JobQueue::updateDocumentRevision() -{ - documents.update({FileContainer(filePath1, Utf8String(), true, 1)}); -} - -void JobQueue::updateUnsavedFiles() -{ - unsavedFiles.createOrUpdate({FileContainer(filePath1, Utf8String(), true, 1)}); -} - -void JobQueue::removeDocument() -{ - documents.remove({FileContainer(filePath1)}); -} - -} // anonymous diff --git a/tests/unit/unittest/clangjobs-test.cpp b/tests/unit/unittest/clangjobs-test.cpp deleted file mode 100644 index a55a550220..0000000000 --- a/tests/unit/unittest/clangjobs-test.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "processevents-utilities.h" -#include "dummyclangipcclient.h" - -#include <clangdocument.h> -#include <clangjobs.h> -#include <filecontainer.h> -#include <clangdocuments.h> -#include <unsavedfiles.h> - -#include <clang-c/Index.h> - -using namespace ClangBackEnd; - -using testing::IsNull; -using testing::NotNull; -using testing::Eq; -using testing::Gt; -using testing::Contains; -using testing::EndsWith; -using testing::AllOf; - -namespace { - -class Jobs : public ::testing::Test -{ -protected: - void SetUp() override; - void TearDown() override; - - bool waitUntilAllJobsFinished(int timeOutInMs = 10000) const; - bool waitUntilJobChainFinished(int timeOutInMs = 10000); - -protected: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - ClangBackEnd::Document document; - DummyIpcClient dummyClientInterface; - - Utf8String filePath1 = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp"); - - ClangBackEnd::Jobs jobs{documents, unsavedFiles, dummyClientInterface}; -}; - -using JobsSlowTest = Jobs; - -TEST_F(Jobs, ProcessEmptyQueue) -{ - const JobRequests jobsStarted = jobs.process(); - - ASSERT_THAT(jobsStarted.size(), Eq(0)); - ASSERT_TRUE(jobs.runningJobs().isEmpty()); -} - -TEST_F(JobsSlowTest, ProcessQueueWithSingleJob) -{ - jobs.add(document, JobRequest::Type::UpdateAnnotations); - - const JobRequests jobsStarted = jobs.process(); - - ASSERT_THAT(jobsStarted.size(), Eq(1)); - ASSERT_THAT(jobs.runningJobs().size(), Eq(1)); -} - -TEST_F(JobsSlowTest, ProcessQueueUntilEmpty) -{ - jobs.add(document, JobRequest::Type::UpdateAnnotations); - jobs.add(document, JobRequest::Type::UpdateAnnotations); - jobs.add(document, JobRequest::Type::UpdateAnnotations); - - jobs.process(); - - waitUntilJobChainFinished(); -} - -TEST_F(JobsSlowTest, IsJobRunning) -{ - jobs.add(document, JobRequest::Type::UpdateAnnotations); - jobs.process(); - - const bool isJobRunning = jobs.isJobRunningForTranslationUnit(document.translationUnit().id()); - - ASSERT_TRUE(isJobRunning); -} - -void Jobs::SetUp() -{ - const QVector<FileContainer> fileContainer{FileContainer(filePath1)}; - document = documents.create(fileContainer).front(); - documents.setVisibleInEditors({filePath1}); - documents.setUsedByCurrentEditor(filePath1); -} - -void Jobs::TearDown() -{ - ASSERT_TRUE(waitUntilAllJobsFinished()); // QFuture/QFutureWatcher is implemented with events -} - -bool Jobs::waitUntilAllJobsFinished(int timeOutInMs) const -{ - const auto noJobsRunningAnymore = [this](){ return jobs.runningJobs().isEmpty(); }; - - return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs); -} - -bool Jobs::waitUntilJobChainFinished(int timeOutInMs) -{ - const auto noJobsRunningAnymore = [this]() { - return jobs.runningJobs().isEmpty() && jobs.queue().isEmpty(); - }; - - return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs); -} - -} // anonymous diff --git a/tests/unit/unittest/clangparsesupportivetranslationunitjob-test.cpp b/tests/unit/unittest/clangparsesupportivetranslationunitjob-test.cpp deleted file mode 100644 index dbb4554a41..0000000000 --- a/tests/unit/unittest/clangparsesupportivetranslationunitjob-test.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangasyncjob-base.h" - -#include <clangparsesupportivetranslationunitjob.h> -#include <clangtranslationunits.h> - -using namespace ClangBackEnd; - -using testing::Eq; -using testing::Not; -using testing::_; - -namespace { - -class ParseSupportiveTranslationUnitJob : public ClangAsyncJobTest -{ -protected: - void SetUp() override { BaseSetUp(JobRequest::Type::ParseSupportiveTranslationUnit, job); } - - TimePoint parseTimePointOfDocument(); - -protected: - ClangBackEnd::ParseSupportiveTranslationUnitJob job; -}; - -using ParseSupportiveTranslationUnitJobSlowTest = ParseSupportiveTranslationUnitJob; - -TEST_F(ParseSupportiveTranslationUnitJob, PrepareAsyncRun) -{ - job.setContext(jobContext); - - ASSERT_TRUE(job.prepareAsyncRun()); -} - -TEST_F(ParseSupportiveTranslationUnitJobSlowTest, RunAsync) -{ - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -} // anonymous diff --git a/tests/unit/unittest/clangreferencescollector-test.cpp b/tests/unit/unittest/clangreferencescollector-test.cpp deleted file mode 100644 index bb04d8c8d1..0000000000 --- a/tests/unit/unittest/clangreferencescollector-test.cpp +++ /dev/null @@ -1,506 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "unittest-utility-functions.h" - -#include <clangsupport_global.h> -#include <clangreferencescollector.h> -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangtranslationunit.h> -#include <fixitcontainer.h> -#include <sourcelocationcontainer.h> -#include <sourcerangecontainer.h> -#include <unsavedfiles.h> - -#include <utils/qtcassert.h> - -#include <clang-c/Index.h> - -using ::testing::Contains; -using ::testing::Not; -using ::testing::ContainerEq; -using ::testing::Eq; - -using ::ClangBackEnd::SourceLocationContainer; -using ::ClangBackEnd::Document; -using ::ClangBackEnd::UnsavedFiles; -using ::ClangBackEnd::ReferencesResult; -using ::ClangBackEnd::SourceRangeContainer; - -using References = QVector<SourceRangeContainer>; - -namespace { - -struct Data { - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Document document{Utf8StringLiteral(TESTDATA_DIR"/references.cpp"), - UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++14")}), - {}, - documents}; -}; - -class ReferencesCollector : public ::testing::Test -{ -protected: - ReferencesResult getReferences(uint line, uint column) - { - return document.translationUnit().references(line, column); - } - - SourceLocationContainer createSourceLocation(uint line, uint column) const - { - return SourceLocationContainer(document.filePath(), line, column); - } - - SourceRangeContainer createSourceRange(uint line, uint column, uint length) const - { - return SourceRangeContainer { - createSourceLocation(line, column), - createSourceLocation(line, column + length) - }; - } - - static void SetUpTestCase(); - static void TearDownTestCase(); - -protected: - static std::unique_ptr<const Data> data; - const Document &document{data->document}; -}; - -// This test is not strictly needed as the plugin is supposed to put the cursor -// on the identifier start. -TEST_F(ReferencesCollector, CursorNotOnIdentifier) -{ - const ReferencesResult expected { false, {}, }; - - const ReferencesResult actual = getReferences(3, 5); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, LocalVariableWithSingleUse) -{ - const ReferencesResult expected { - true, - {createSourceRange(3, 9, 3)}, - }; - - const ReferencesResult actual = getReferences(3, 9); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, LocalVariableWithTwoUses) -{ - const ReferencesResult expected { - true, - {createSourceRange(10, 9, 3), - createSourceRange(11, 12, 3)}, - }; - - const ReferencesResult actual = getReferences(10, 9); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, ClassName) -{ - const ReferencesResult expected { - false, - {createSourceRange(16, 7, 3), - createSourceRange(19, 5, 3)}, - }; - - const ReferencesResult actual = getReferences(16, 7); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, Namespace) -{ - const ReferencesResult expected { - false, - {createSourceRange(24, 11, 1), - createSourceRange(25, 11, 1), - createSourceRange(26, 1, 1)}, - }; - - const ReferencesResult actual = getReferences(24, 11); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, ClassNameDeclaredWithUsing) -{ - const ReferencesResult expected { - false, - {createSourceRange(30, 21, 3), - createSourceRange(31, 10, 3)}, - }; - - const ReferencesResult actual = getReferences(30, 21); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, ClassNameForwardDeclared) -{ - const ReferencesResult expected { - false, - {createSourceRange(35, 7, 3), - createSourceRange(36, 14, 3)}, - }; - - const ReferencesResult actual = getReferences(35, 7); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, ClassNameAndNewExpression) -{ - const ReferencesResult expected { - false, - {createSourceRange(40, 7, 3), - createSourceRange(43, 9, 3)}, - }; - - const ReferencesResult actual = getReferences(40, 7); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, InstantiatedTemplateObject) -{ - const ReferencesResult expected { - true, - {createSourceRange(52, 19, 3), - createSourceRange(53, 5, 3)}, - }; - - const ReferencesResult actual = getReferences(52, 19); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, VariableInTemplate) -{ - const ReferencesResult expected { - true, - {createSourceRange(62, 13, 3), - createSourceRange(63, 11, 3)}, - }; - - const ReferencesResult actual = getReferences(62, 13); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, MemberInTemplate) -{ - const ReferencesResult expected { - false, - {createSourceRange(64, 16, 3), - createSourceRange(67, 7, 3)}, - }; - - const ReferencesResult actual = getReferences(67, 7); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, TemplateType) -{ - const ReferencesResult expected { - false, - {createSourceRange(58, 19, 1), - createSourceRange(60, 5, 1), - createSourceRange(67, 5, 1)}, - }; - - const ReferencesResult actual = getReferences(58, 19); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, MemberAccessIntoTemplateParameter) -{ - const ReferencesResult expected { false, {}, }; - - const ReferencesResult actual = getReferences(76, 9); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, ConstructorAsType) -{ - const ReferencesResult expected { - false, - {createSourceRange(81, 8, 3), - createSourceRange(82, 5, 3), - createSourceRange(83, 6, 3)}, - }; - - const ReferencesResult actual = getReferences(82, 5); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, OverloadsFreeStanding) -{ - const ReferencesResult expected { - false, - {createSourceRange(88, 5, 3), - createSourceRange(89, 5, 3)}, - }; - - const ReferencesResult actual = getReferences(88, 5); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, OverloadsMemberFunctions) -{ - const ReferencesResult expected { - false, - {createSourceRange(94, 9, 3), - createSourceRange(95, 9, 3)}, - }; - - const ReferencesResult actual = getReferences(94, 9); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, FunctionAndTemplateFunction) -{ - const ReferencesResult expected { - false, - {createSourceRange(100, 26, 3), - createSourceRange(101, 5, 3)}, - }; - - const ReferencesResult actual = getReferences(100, 26); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, FunctionAndTemplateFunctionAsMember) -{ - const ReferencesResult expected { - false, - {createSourceRange(106, 30, 3), - createSourceRange(107, 9, 3)}, - }; - - const ReferencesResult actual = getReferences(106, 30); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, EnumType) -{ - const ReferencesResult expected { - false, - {createSourceRange(112, 6, 2), - createSourceRange(113, 8, 2)}, - }; - - const ReferencesResult actual = getReferences(112, 6); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, LambdaCapturedObject) -{ - const ReferencesResult expected { - true, - {createSourceRange(122, 15, 3), - createSourceRange(122, 33, 3)}, - }; - - const ReferencesResult actual = getReferences(122, 15); - - ASSERT_THAT(actual, expected); -} - -//// Disabled because it looks like the lambda initializer is not yet exposed by libclang. -TEST_F(ReferencesCollector, DISABLED_LambdaCaptureInitializer) -{ - const ReferencesResult expected { - true, - {createSourceRange(121, 19, 3), - createSourceRange(122, 19, 3)}, - }; - - const ReferencesResult actual = getReferences(122, 19); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, TemplateSpecialization) -{ - const ReferencesResult expected { - false, - {createSourceRange(127, 25, 3), - createSourceRange(128, 25, 3), - createSourceRange(129, 18, 3)}, - }; - - const ReferencesResult actual = getReferences(127, 25); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, TemplateDependentName) -{ - const ReferencesResult expected { - false, - {createSourceRange(133, 34, 3)}, - }; - - const ReferencesResult actual = getReferences(133, 34); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, FunctionCallAndDefinition) -{ - const ReferencesResult expected { - false, - {createSourceRange(140, 5, 3), - createSourceRange(142, 25, 3)}, - }; - - const ReferencesResult actual = getReferences(140, 5); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, ObjectLikeMacro) -{ - const ReferencesResult expected { - false, - {createSourceRange(147, 9, 3), - createSourceRange(150, 12, 3)}, - }; - - const ReferencesResult actual = getReferences(147, 9); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, FunctionLikeMacro) -{ - const ReferencesResult expected { - false, - {createSourceRange(155, 9, 3), - createSourceRange(158, 12, 3)}, - }; - - const ReferencesResult actual = getReferences(155, 9); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, ArgumentToFunctionLikeMacro) -{ - const ReferencesResult expected { - true, - {createSourceRange(156, 27, 3), - createSourceRange(158, 16, 3)}, - }; - - const ReferencesResult actual = getReferences(156, 27); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, OverloadedBraceOperatorArgument) -{ - const ReferencesResult expected { - true, - {createSourceRange(171, 7, 1), - createSourceRange(172, 7, 1), - createSourceRange(172, 12, 1), - createSourceRange(173, 7, 1), - createSourceRange(173, 10, 1)}, - }; - - const ReferencesResult actual = getReferences(172, 7); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, OverloadedParenOperatorSecondArgument) -{ - const ReferencesResult expected { - true, - {createSourceRange(171, 7, 1), - createSourceRange(172, 7, 1), - createSourceRange(172, 12, 1), - createSourceRange(173, 7, 1), - createSourceRange(173, 10, 1)}, - }; - - const ReferencesResult actual = getReferences(173, 10); - - ASSERT_THAT(actual, expected); -} - -TEST_F(ReferencesCollector, OverloadedOperatorsArgumentsFromOutside) -{ - const ReferencesResult expected { - true, - {createSourceRange(171, 7, 1), - createSourceRange(172, 7, 1), - createSourceRange(172, 12, 1), - createSourceRange(173, 7, 1), - createSourceRange(173, 10, 1)}, - }; - - const ReferencesResult actual = getReferences(171, 7); - - ASSERT_THAT(actual, expected); -} - -std::unique_ptr<const Data> ReferencesCollector::data; - -void ReferencesCollector::SetUpTestCase() -{ - data = std::make_unique<const Data>(); - - data->document.parse(); -} - -void ReferencesCollector::TearDownTestCase() -{ - data.reset(); -} - -} // anonymous namespace diff --git a/tests/unit/unittest/clangrequestannotationsjob-test.cpp b/tests/unit/unittest/clangrequestannotationsjob-test.cpp deleted file mode 100644 index 9fb80d2ff0..0000000000 --- a/tests/unit/unittest/clangrequestannotationsjob-test.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangasyncjob-base.h" - -#include <clangrequestannotationsjob.h> - -using namespace ClangBackEnd; - -using testing::_; - -namespace { - -class RequestAnnotationsJob : public ClangAsyncJobTest -{ -protected: - void SetUp() override { BaseSetUp(JobRequest::Type::RequestAnnotations, job); } - -protected: - ClangBackEnd::RequestAnnotationsJob job; -}; - -TEST_F(RequestAnnotationsJob, PrepareAsyncRun) -{ - job.setContext(jobContext); - - ASSERT_TRUE(job.prepareAsyncRun()); -} - -TEST_F(RequestAnnotationsJob, RunAsync) -{ - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(RequestAnnotationsJob, SendAnnotations) -{ - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, annotations(_)).Times(1); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(RequestAnnotationsJob, DontSendAnnotationsIfDocumentWasClosed) -{ - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, annotations(_)).Times(0); - - job.runAsync(); - documents.remove({FileContainer{filePath}}); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -} // anonymous diff --git a/tests/unit/unittest/clangrequestreferencesjob-test.cpp b/tests/unit/unittest/clangrequestreferencesjob-test.cpp deleted file mode 100644 index 83d7d97a25..0000000000 --- a/tests/unit/unittest/clangrequestreferencesjob-test.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangasyncjob-base.h" - -#include <clangrequestreferencesjob.h> - -using namespace ClangBackEnd; - -using testing::_; -using testing::Eq; -using testing::Property; - -namespace { - -class RequestReferencesJob : public ClangAsyncJobTest -{ -protected: - void SetUp() override { BaseSetUp(JobRequest::Type::RequestReferences, job); } - -protected: - ClangBackEnd::RequestReferencesJob job; -}; - -TEST_F(RequestReferencesJob, PrepareAsyncRun) -{ - job.setContext(jobContext); - - ASSERT_TRUE(job.prepareAsyncRun()); -} - -TEST_F(RequestReferencesJob, RunAsync) -{ - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(RequestReferencesJob, SendReferences) -{ - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, references(_)).Times(1); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(RequestReferencesJob, ForwardTicketNumber) -{ - jobRequest.ticketNumber = static_cast<quint64>(99); - jobContextWithMockClient = JobContext(jobRequest, &documents, &unsavedFiles, &mockIpcClient); - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, - references(Field(&ReferencesMessage::ticketNumber, Eq(jobRequest.ticketNumber)))) - .Times(1); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(RequestReferencesJob, DontSendReferencesIfDocumentWasClosed) -{ - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, references(_)).Times(0); - - job.runAsync(); - documents.remove({FileContainer{filePath}}); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(RequestReferencesJob, DontSendReferencesIfDocumentRevisionChanged) -{ - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, references(_)).Times(0); - - job.runAsync(); - documents.update({FileContainer(filePath, Utf8String(), true, 99)}); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -} // anonymous diff --git a/tests/unit/unittest/clangresumedocumentjob-test.cpp b/tests/unit/unittest/clangresumedocumentjob-test.cpp deleted file mode 100644 index 9582b0c0d1..0000000000 --- a/tests/unit/unittest/clangresumedocumentjob-test.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangasyncjob-base.h" - -#include <clangresumedocumentjob.h> - -using namespace ClangBackEnd; - -using testing::_; - -namespace { - -class ResumeDocumentJob : public ClangAsyncJobTest -{ -protected: - void SetUp() override { BaseSetUp(JobRequest::Type::ResumeDocument, job); } - void suspendDocument() - { - document.parse(); - document.translationUnit().suspend(); - document.setIsSuspended(true); - } - -protected: - ClangBackEnd::ResumeDocumentJob job; -}; - -TEST_F(ResumeDocumentJob, PrepareAsyncRun) -{ - job.setContext(jobContext); - - ASSERT_TRUE(job.prepareAsyncRun()); -} - -TEST_F(ResumeDocumentJob, RunAsync) -{ - suspendDocument(); - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(ResumeDocumentJob, DocumentIsResumedAfterRun) -{ - suspendDocument(); - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - ASSERT_TRUE(waitUntilJobFinished(job)); - - ASSERT_FALSE(document.isSuspended()); -} - -TEST_F(ResumeDocumentJob, SendsAnnotationsAfterResume) -{ - suspendDocument(); - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, annotations(_)).Times(1); - - job.runAsync(); - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -} // anonymous diff --git a/tests/unit/unittest/clangstring-test.cpp b/tests/unit/unittest/clangstring-test.cpp deleted file mode 100644 index 8e30da93e2..0000000000 --- a/tests/unit/unittest/clangstring-test.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <clangstring.h> - -#include <utf8string.h> - -#include <clang-c/CXString.h> -#include <clang-c/Index.h> - -namespace { - -using ::testing::StrEq; -using ::testing::Eq; - -using ClangBackEnd::ClangString; - -TEST(ClangString, ConvertToUtf8String) -{ - const CXString cxString = { "text", 0}; - - ASSERT_THAT(Utf8String(ClangString(cxString)), Utf8StringLiteral("text")); -} - -TEST(ClangString, ConvertNullStringToUtf8String) -{ - const CXString cxString = { 0, 0}; - - ASSERT_THAT(Utf8String(ClangString(cxString)), Utf8String()); -} - -TEST(ClangString, MoveContructor) -{ - ClangString text(CXString{ "text", 0}); - - const ClangString text2 = std::move(text); - - ASSERT_TRUE(text.isNull()); - ASSERT_FALSE(text2.isNull()); -} - -TEST(ClangString, MoveAssigment) -{ - ClangString text(CXString{ "text", 0}); - - ClangString text2 = std::move(text); - text = std::move(text2); - - ASSERT_TRUE(text2.isNull()); - ASSERT_FALSE(text.isNull()); -} - -TEST(ClangString, MoveSelfAssigment) -{ - ClangString text(CXString{ "text", 0}); - - text = std::move(text); - - ASSERT_FALSE(text.isNull()); -} - -TEST(ClangString, SpellingAsCString) -{ - ClangString text(CXString{"text", 0}); - - ASSERT_THAT(text.cString(), StrEq("text")); -} - -TEST(ClangString, EqualBetweenClangStrings) -{ - ClangString text(CXString{"text", 0}); - ClangString text2(CXString{"text", 0}); - - bool textIsEqual = text == text2; - - ASSERT_TRUE(textIsEqual); -} - -TEST(ClangString, NotEqualBetweenClangStrings) -{ - ClangString text(CXString{"text", 0}); - ClangString text2(CXString{"text ", 0}); - - bool textIsNotEqual = text != text2; - - ASSERT_TRUE(textIsNotEqual); -} - -TEST(ClangString, EqualClangStringAndCString) -{ - ClangString text(CXString{"text", 0}); - - bool textIsEqual = text == "text"; - - ASSERT_TRUE(textIsEqual); -} - -TEST(ClangString, NotEqualClangStringAndCString) -{ - ClangString text(CXString{"text", 0}); - - bool textIsNotEqual = text != "text "; - - ASSERT_TRUE(textIsNotEqual); -} - -TEST(ClangString, EqualCStringAndClangString) -{ - ClangString text(CXString{"text", 0}); - - bool textIsEqual = "text" == text; - - ASSERT_TRUE(textIsEqual); -} - -TEST(ClangString, NotEqualCStringAndClangString) -{ - ClangString text(CXString{"text", 0}); - - bool textIsNotEqual = "text " != text; - - ASSERT_TRUE(textIsNotEqual); -} - -TEST(ClangString, EqualClangStringPointerAndCString) -{ - ClangString text(CXString{"text", 0}); - const char *cString = "text"; - - bool textIsEqual = cString == text; - - ASSERT_TRUE(textIsEqual); -} - -TEST(ClangString, NotEqualClangStringPointerAndCString) -{ - ClangString text(CXString{"text", 0}); - const char *cString = "text "; - - bool textIsNotEqual = cString != text; - - ASSERT_TRUE(textIsNotEqual); -} - -TEST(ClangString, EqualCStringAndClangStringPointer) -{ - ClangString text(CXString{"text", 0}); - const char *cString = "text"; - - bool textIsEqual = text == cString; - - ASSERT_TRUE(textIsEqual); -} - -TEST(ClangString, NotEqualCStringAndClangStringPointer) -{ - ClangString text(CXString{"text", 0}); - const char *cString = "text "; - - bool textIsNotEqual = text != cString; - - ASSERT_TRUE(textIsNotEqual); -} - -TEST(ClangString, NullStringHasNoContent) -{ - ClangString text(CXString{nullptr, 0}); - - bool hasContent = text.hasContent(); - - ASSERT_FALSE(hasContent); -} - -TEST(ClangString, EmptyStringHasNoContent) -{ - ClangString text(CXString{"", 0}); - - bool hasContent = text.hasContent(); - - ASSERT_FALSE(hasContent); -} - -TEST(ClangString, StringHasNoContent) -{ - ClangString text(CXString{"text", 0}); - - bool hasContent = text.hasContent(); - - ASSERT_TRUE(hasContent); -} - -} diff --git a/tests/unit/unittest/clangsupportivetranslationunitinitializer-test.cpp b/tests/unit/unittest/clangsupportivetranslationunitinitializer-test.cpp deleted file mode 100644 index c62b803a71..0000000000 --- a/tests/unit/unittest/clangsupportivetranslationunitinitializer-test.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include "dummyclangipcclient.h" -#include "processevents-utilities.h" - -#include <clangbackend_global.h> -#include <clangdocuments.h> -#include <clangexceptions.h> -#include <clangsupportivetranslationunitinitializer.h> -#include <clangtranslationunit.h> -#include <clangtranslationunits.h> -#include <utf8string.h> - -#include <clang-c/Index.h> - -#include <memory> - -using namespace ClangBackEnd; - -using testing::Eq; - -namespace { - -class SupportiveTranslationUnitInitializer : public ::testing::Test -{ -protected: - void SetUp() override; - void parse(); - Jobs::RunningJob createRunningJob(JobRequest::Type type) const; - - void assertNoJobIsRunningAndEmptyQueue(); - void assertSingleJobRunningAndEmptyQueue(); - - bool waitUntilJobChainFinished(int timeOutInMs = 10000) const; - -protected: - Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp")}; - - UnsavedFiles unsavedFiles; - const QVector<FileContainer> fileContainer{FileContainer(filePath)}; - Documents documents{unsavedFiles}; - Document document{documents.create(fileContainer).front()}; - DummyIpcClient dummyClientInterface; - - Jobs jobs{documents, unsavedFiles, dummyClientInterface}; - - ClangBackEnd::SupportiveTranslationUnitInitializer initializer{document, jobs}; -}; - -using SupportiveTranslationUnitInitializerSlowTest = SupportiveTranslationUnitInitializer; - -TEST_F(SupportiveTranslationUnitInitializer, HasInitiallyNotInitializedState) -{ - ASSERT_THAT(initializer.state(), Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::NotInitialized)); -} - -TEST_F(SupportiveTranslationUnitInitializer, StartInitializingAbortsIfDocumentIsClosed) -{ - documents.remove({FileContainer(filePath)}); - - initializer.startInitializing(); - - assertNoJobIsRunningAndEmptyQueue(); - ASSERT_THAT(initializer.state(), Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::Aborted)); -} - -TEST_F(SupportiveTranslationUnitInitializerSlowTest, StartInitializingAddsTranslationUnit) -{ - initializer.startInitializing(); - - ASSERT_THAT(document.translationUnits().size(), Eq(2)); - ASSERT_FALSE(document.translationUnits().areAllTranslationUnitsParsed()); -} - -TEST_F(SupportiveTranslationUnitInitializerSlowTest, StartInitializingStartsJob) -{ - initializer.startInitializing(); - - assertSingleJobRunningAndEmptyQueue(); - const Jobs::RunningJob runningJob = jobs.runningJobs().first(); - ASSERT_THAT(runningJob.jobRequest.type, JobRequest::Type::ParseSupportiveTranslationUnit); -} - -TEST_F(SupportiveTranslationUnitInitializerSlowTest, Abort) -{ - initializer.startInitializing(); - assertSingleJobRunningAndEmptyQueue(); - - initializer.abort(); - - ASSERT_THAT(initializer.state(), - Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::Aborted)); - ASSERT_FALSE(jobs.jobFinishedCallback()); -} - -TEST_F(SupportiveTranslationUnitInitializer, CheckIfParseJobFinishedAbortsIfDocumentIsClosed) -{ - documents.remove({FileContainer(filePath)}); - initializer.setState(ClangBackEnd::SupportiveTranslationUnitInitializer::State::WaitingForParseJob); - const Jobs::RunningJob runningJob = createRunningJob(JobRequest::Type::ParseSupportiveTranslationUnit); - - initializer.checkIfParseJobFinished(runningJob); - - assertNoJobIsRunningAndEmptyQueue(); - ASSERT_THAT(initializer.state(), Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::Aborted)); -} - -TEST_F(SupportiveTranslationUnitInitializerSlowTest, CheckIfParseJobFinishedStartsJob) -{ - parse(); - initializer.setState(ClangBackEnd::SupportiveTranslationUnitInitializer::State::WaitingForParseJob); - Jobs::RunningJob runningJob = createRunningJob(JobRequest::Type::ParseSupportiveTranslationUnit); - - initializer.checkIfParseJobFinished(runningJob); - jobs.process(); - - ASSERT_THAT(jobs.runningJobs(), IsEmpty()); - ASSERT_THAT(jobs.queue(), IsEmpty()); -} - -TEST_F(SupportiveTranslationUnitInitializerSlowTest, FullRun) -{ - parse(); - initializer.startInitializing(); - - waitUntilJobChainFinished(); - ASSERT_THAT(initializer.state(), Eq(ClangBackEnd::SupportiveTranslationUnitInitializer::State::Initialized)); -} - -void SupportiveTranslationUnitInitializer::SetUp() -{ - documents.setVisibleInEditors({filePath}); - documents.setUsedByCurrentEditor(filePath); - - const auto isDocumentClosed = [this](const Utf8String &filePath) { - return !documents.hasDocument(filePath); - }; - initializer.setIsDocumentClosedChecker(isDocumentClosed); -} - -void SupportiveTranslationUnitInitializer::parse() -{ - document.parse(); -} - -Jobs::RunningJob SupportiveTranslationUnitInitializer::createRunningJob(JobRequest::Type type) const -{ - const JobRequest jobRequest = jobs.createJobRequest(document, - type, - PreferredTranslationUnit::LastUninitialized); - return Jobs::RunningJob{jobRequest, Utf8String(), QFuture<void>()}; -} - -void SupportiveTranslationUnitInitializer::assertNoJobIsRunningAndEmptyQueue() -{ - ASSERT_TRUE(jobs.runningJobs().isEmpty()); - ASSERT_TRUE(jobs.queue().isEmpty()); -} - -void SupportiveTranslationUnitInitializer::assertSingleJobRunningAndEmptyQueue() -{ - ASSERT_THAT(jobs.runningJobs().size(), Eq(1)); - ASSERT_TRUE(jobs.queue().isEmpty()); -} - -bool SupportiveTranslationUnitInitializer::waitUntilJobChainFinished(int timeOutInMs) const -{ - const auto noJobsRunningAnymore = [this]() { - return jobs.runningJobs().isEmpty() && jobs.queue().isEmpty(); - }; - - return ProcessEventUtilities::processEventsUntilTrue(noJobsRunningAnymore, timeOutInMs); -} - -} // anonymous namespace diff --git a/tests/unit/unittest/clangsuspenddocumentjob-test.cpp b/tests/unit/unittest/clangsuspenddocumentjob-test.cpp deleted file mode 100644 index b9f92f3beb..0000000000 --- a/tests/unit/unittest/clangsuspenddocumentjob-test.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangasyncjob-base.h" - -#include <clangsuspenddocumentjob.h> - -using namespace ClangBackEnd; - -namespace { - -class SuspendDocumentJob : public ClangAsyncJobTest -{ -protected: - void SetUp() override { BaseSetUp(JobRequest::Type::SuspendDocument, job); } - -protected: - ClangBackEnd::SuspendDocumentJob job; -}; - -TEST_F(SuspendDocumentJob, PrepareAsyncRun) -{ - job.setContext(jobContext); - - ASSERT_TRUE(job.prepareAsyncRun()); -} - -TEST_F(SuspendDocumentJob, RunAsync) -{ - document.parse(); - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(SuspendDocumentJob, DocumentIsSuspendedAfterRun) -{ - document.parse(); - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - ASSERT_TRUE(waitUntilJobFinished(job)); - - ASSERT_TRUE(document.isSuspended()); -} - -} // anonymous diff --git a/tests/unit/unittest/clangtooltipinfo-test.cpp b/tests/unit/unittest/clangtooltipinfo-test.cpp deleted file mode 100644 index bb1fbb8a44..0000000000 --- a/tests/unit/unittest/clangtooltipinfo-test.cpp +++ /dev/null @@ -1,696 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "rundocumentparse-utility.h" - -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangsupport_global.h> -#include <clangtooltipinfocollector.h> -#include <clangtranslationunit.h> -#include <fixitcontainer.h> -#include <sourcelocationcontainer.h> -#include <sourcerangecontainer.h> -#include <unsavedfiles.h> - -#include <utils/qtcassert.h> - -#include <clang-c/Index.h> - -using ::ClangBackEnd::SourceLocationContainer; -using ::ClangBackEnd::Document; -using ::ClangBackEnd::UnsavedFiles; -using ::ClangBackEnd::ToolTipInfo; -using ::ClangBackEnd::SourceRangeContainer; - -namespace { - -#define CHECK_MEMBER(actual, expected, memberName) \ - if (actual.memberName != expected.memberName) { \ - *result_listener << #memberName " is " + PrintToString(actual.memberName) \ - << " and not " + PrintToString(expected.memberName); \ - return false; \ - } - -MATCHER_P(IsToolTip, expected, std::string(negation ? "isn't" : "is") + PrintToString(expected)) -{ - CHECK_MEMBER(arg, expected, text); - CHECK_MEMBER(arg, expected, briefComment); - - CHECK_MEMBER(arg, expected, qdocIdCandidates); - CHECK_MEMBER(arg, expected, qdocMark); - CHECK_MEMBER(arg, expected, qdocCategory); - - CHECK_MEMBER(arg, expected, sizeInBytes); - - return true; -} - -MATCHER_P(IsQdocToolTip, expected, std::string(negation ? "isn't" : "is") + PrintToString(expected)) -{ - CHECK_MEMBER(arg, expected, qdocIdCandidates); - CHECK_MEMBER(arg, expected, qdocMark); - CHECK_MEMBER(arg, expected, qdocCategory); - - return true; -} - -#undef CHECK_MEMBER - -struct Data { - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Document document{Utf8StringLiteral(TESTDATA_DIR "/tooltipinfo.cpp"), - {Utf8StringLiteral("-std=c++14")}, - {}, - documents}; - UnitTest::RunDocumentParse _1{document}; -}; - -class ToolTipInfo : public ::testing::Test -{ -protected: - ::ToolTipInfo tooltip(uint line, uint column) - { - return d->document.translationUnit().tooltip(d->unsavedFiles, - Utf8StringLiteral("UTF-8"), - line, - column); - } - - static void SetUpTestCase(); - static void TearDownTestCase(); - -private: - static std::unique_ptr<Data> d; -}; - -TEST_F(ToolTipInfo, LocalVariableInt) -{ - const ::ToolTipInfo actual = tooltip(3, 5); - - ASSERT_THAT(actual, IsToolTip(::ToolTipInfo(Utf8StringLiteral("int")))); -} - -TEST_F(ToolTipInfo, LocalVariableConstInt) -{ - ASSERT_THAT(tooltip(211, 19), IsToolTip(::ToolTipInfo(Utf8StringLiteral("const int")))); -} - -TEST_F(ToolTipInfo, FileScopeVariableConstInt) -{ - ASSERT_THAT(tooltip(206, 11), IsToolTip(::ToolTipInfo(Utf8StringLiteral("const int")))); -} - -TEST_F(ToolTipInfo, LocalVariablePointerToConstInt) -{ - const ::ToolTipInfo actual = tooltip(4, 5); - - ASSERT_THAT(actual, IsToolTip(::ToolTipInfo(Utf8StringLiteral("const int *")))); -} - -TEST_F(ToolTipInfo, LocalParameterVariableConstRefCustomType) -{ - ::ToolTipInfo expected(Utf8StringLiteral("const Foo &")); - expected.qdocIdCandidates = {Utf8StringLiteral("Foo")}; - expected.qdocMark = Utf8StringLiteral("Foo"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(12, 12); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, LocalNonParameterVariableConstRefCustomType) -{ - ::ToolTipInfo expected(Utf8StringLiteral("const Foo")); - expected.qdocIdCandidates = {Utf8StringLiteral("Foo")}; - expected.qdocMark = Utf8StringLiteral("Foo"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(14, 5); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, MemberVariable) -{ - const ::ToolTipInfo actual = tooltip(12, 16); - - ASSERT_THAT(actual, IsToolTip(::ToolTipInfo(Utf8StringLiteral("int")))); -} - -TEST_F(ToolTipInfo, MemberFunctionCall_QualifiedName) -{ - const ::ToolTipInfo actual = tooltip(21, 9); - - ASSERT_THAT(actual.text, Utf8StringLiteral("int Bar::mem()")); -} - -// ChangeLog: Show extra specifiers. For functions e.g.: virtual, inline, explicit, const, volatile -TEST_F(ToolTipInfo, MemberFunctionCall_ExtraSpecifiers) -{ - const ::ToolTipInfo actual = tooltip(22, 9); - - ASSERT_THAT(actual.text, Utf8StringLiteral("virtual int Bar::virtualConstMem() const")); -} - -TEST_F(ToolTipInfo, MemberFunctionCall_qdocIdCandidates) -{ - const ::ToolTipInfo actual = tooltip(21, 9); - - ASSERT_THAT(actual.qdocIdCandidates, ElementsAre(Utf8StringLiteral("Bar::mem"), - Utf8StringLiteral("mem"))); -} - -TEST_F(ToolTipInfo, MemberFunctionCall_qdocMark_FIXLIBCLANG_CHECKED) -{ - const ::ToolTipInfo actual = tooltip(21, 9); - - ASSERT_THAT(actual.qdocMark, Utf8StringLiteral("mem()")); -} - -// TODO: Check what is really needed for qdoc before implementing this one. -TEST_F(ToolTipInfo, DISABLED_MemberFunctionCall_qdocMark_extraSpecifiers) -{ - const ::ToolTipInfo actual = tooltip(22, 9); - - ASSERT_THAT(actual.qdocMark, Utf8StringLiteral("virtualConstMem() const")); -} - -TEST_F(ToolTipInfo, MemberFunctionCall_qdocCategory) -{ - const ::ToolTipInfo actual = tooltip(21, 9); - - ASSERT_THAT(actual.qdocCategory, ::ToolTipInfo::Function); -} - -// TODO: Show the template parameter type, too: "template<typename T>...)" -TEST_F(ToolTipInfo, TemplateFunctionCall) -{ - const ::ToolTipInfo actual = tooltip(30, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("template<> void t<Foo>(int foo)")); -} - -TEST_F(ToolTipInfo, TemplateFunctionCall_qdocIdCandidates) -{ - const ::ToolTipInfo actual = tooltip(30, 5); - - ASSERT_THAT(actual.qdocIdCandidates, ElementsAre(Utf8StringLiteral("t"))); -} - -TEST_F(ToolTipInfo, TemplateFunctionCall_qdocMark_FIXLIBCLANG_CHECKED) -{ - const ::ToolTipInfo actual = tooltip(30, 5); - - ASSERT_THAT(actual.qdocMark, Utf8StringLiteral("t(int)")); -} - -TEST_F(ToolTipInfo, TemplateFunctionCall_qdocCategory) -{ - const ::ToolTipInfo actual = tooltip(30, 5); - - ASSERT_THAT(actual.qdocCategory, ::ToolTipInfo::Function); -} - -TEST_F(ToolTipInfo, BriefComment) -{ - const ::ToolTipInfo actual = tooltip(41, 5); - - ASSERT_THAT(actual.briefComment, Utf8StringLiteral("This is a crazy function.")); -} - -TEST_F(ToolTipInfo, Enum) -{ - ::ToolTipInfo expected(Utf8StringLiteral("EnumType")); - expected.qdocIdCandidates = {Utf8StringLiteral("EnumType")}; - expected.qdocMark = Utf8StringLiteral("EnumType"); - expected.qdocCategory = ::ToolTipInfo::Enum; - - const ::ToolTipInfo actual = tooltip(49, 12); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, Enumerator) -{ - ::ToolTipInfo expected(Utf8StringLiteral("6")); - expected.qdocIdCandidates = {Utf8StringLiteral("Custom")}; - expected.qdocMark = Utf8StringLiteral("EnumType"); - expected.qdocCategory = ::ToolTipInfo::Enum; - - const ::ToolTipInfo actual = tooltip(49, 22); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, TemplateTypeFromParameter) -{ - ::ToolTipInfo expected(Utf8StringLiteral("const Baz<int> &")); - expected.qdocIdCandidates = {Utf8StringLiteral("Baz")}; - expected.qdocMark = Utf8StringLiteral("Baz"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(55, 25); - - ASSERT_THAT(actual, IsQdocToolTip(expected)); -} - -TEST_F(ToolTipInfo, TemplateTypeFromNonParameter) -{ - ::ToolTipInfo expected(Utf8StringLiteral("Baz<int>")); - expected.qdocIdCandidates = {Utf8StringLiteral("Baz")}; - expected.qdocMark = Utf8StringLiteral("Baz"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(56, 19); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, IncludeDirective) -{ - ::ToolTipInfo expected( - QDir::toNativeSeparators(Utf8StringLiteral(TESTDATA_DIR "/tooltipinfo.h"))); - expected.qdocIdCandidates = {Utf8StringLiteral("tooltipinfo.h")}; - expected.qdocMark = Utf8StringLiteral("tooltipinfo.h"); - expected.qdocCategory = ::ToolTipInfo::Brief; - - const ::ToolTipInfo actual = tooltip(59, 11); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, MacroUse_WithMacroFromSameFile) -{ - const ::ToolTipInfo actual = tooltip(66, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("#define MACRO_FROM_MAINFILE(x) x + 3")); -} - -TEST_F(ToolTipInfo, MacroUse_WithMacroFromHeader) -{ - const ::ToolTipInfo actual = tooltip(67, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("#define MACRO_FROM_HEADER(x) x + \\\n x + \\\n x")); -} - -TEST_F(ToolTipInfo, MacroUse_qdoc) -{ - ::ToolTipInfo expected; - expected.qdocIdCandidates = {Utf8StringLiteral("MACRO_FROM_MAINFILE")}; - expected.qdocMark = Utf8StringLiteral("MACRO_FROM_MAINFILE"); - expected.qdocCategory = ::ToolTipInfo::Macro; - - const ::ToolTipInfo actual = tooltip(66, 5); - - ASSERT_THAT(actual, IsQdocToolTip(expected)); -} - -TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDirectiveIsQualified) -{ - ::ToolTipInfo expected(Utf8StringLiteral("N::Muu")); - expected.qdocIdCandidates = {Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}; - expected.qdocMark = Utf8StringLiteral("Muu"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(77, 5); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDirectiveOfAliasIsResolvedAndQualified) -{ - ::ToolTipInfo expected(Utf8StringLiteral("N::Muu")); - expected.qdocIdCandidates = {Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}; - expected.qdocMark = Utf8StringLiteral("Muu"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(82, 5); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDeclarationIsQualified) -{ - ::ToolTipInfo expected(Utf8StringLiteral("N::Muu")); - expected.qdocIdCandidates = {Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}; - expected.qdocMark = Utf8StringLiteral("Muu"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(87, 5); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, SizeForClassDefinition) -{ - const ::ToolTipInfo actual = tooltip(92, 8); - - ASSERT_THAT(actual.sizeInBytes, Utf8StringLiteral("2")); -} - -TEST_F(ToolTipInfo, SizeForMemberField) -{ - const ::ToolTipInfo actual = tooltip(95, 10); - - ASSERT_THAT(actual.sizeInBytes, Utf8StringLiteral("1")); -} - -TEST_F(ToolTipInfo, SizeForEnum) -{ - const ::ToolTipInfo actual = tooltip(97, 12); - - ASSERT_THAT(actual.sizeInBytes, Utf8StringLiteral("4")); -} - -TEST_F(ToolTipInfo, SizeForUnion) -{ - const ::ToolTipInfo actual = tooltip(98, 7); - - ASSERT_THAT(actual.sizeInBytes, Utf8StringLiteral("1")); -} - -TEST_F(ToolTipInfo, constexprValue) -{ - ASSERT_THAT(tooltip(204, 12).value.toInt(), 4); - ASSERT_THAT(tooltip(204, 27).value.toInt(), CINDEX_VERSION_MINOR > 59 ? 3 : 4); - ASSERT_THAT(tooltip(204, 30).value.toInt(), 4); - ASSERT_THAT(tooltip(204, 32).value.toInt(), CINDEX_VERSION_MINOR > 59 ? 1 : 4); -} - -TEST_F(ToolTipInfo, Namespace) -{ - ::ToolTipInfo expected(Utf8StringLiteral("X")); - expected.qdocIdCandidates = {Utf8StringLiteral("X")}; - expected.qdocMark = Utf8StringLiteral("X"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(106, 11); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, NamespaceQualified) -{ - ::ToolTipInfo expected(Utf8StringLiteral("X::Y")); - expected.qdocIdCandidates = {Utf8StringLiteral("X::Y"), Utf8StringLiteral("Y")}; - expected.qdocMark = Utf8StringLiteral("Y"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(107, 11); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -// TODO: Show unresolved and resolved name, for F1 try both. -TEST_F(ToolTipInfo, TypeName_ResolveTypeDef) -{ - ::ToolTipInfo expected(Utf8StringLiteral("Ptr<Nuu>")); - expected.qdocIdCandidates = {Utf8StringLiteral("PtrFromTypeDef")}; - expected.qdocMark = Utf8StringLiteral("PtrFromTypeDef"); - expected.qdocCategory = ::ToolTipInfo::Typedef; - - const ::ToolTipInfo actual = tooltip(122, 5); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -// TODO: Show unresolved and resolved name, for F1 try both. -TEST_F(ToolTipInfo, TypeName_ResolveAlias) -{ - ::ToolTipInfo expected(Utf8StringLiteral("Ptr<Nuu>")); - expected.qdocIdCandidates = {Utf8StringLiteral("PtrFromTypeAlias")}; - expected.qdocMark = Utf8StringLiteral("PtrFromTypeAlias"); - expected.qdocCategory = ::ToolTipInfo::Typedef; - - const ::ToolTipInfo actual = tooltip(123, 5); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -// The referenced cursor is a CXCursor_TypeAliasTemplateDecl, its type is invalid -// and so probably clang_getTypedefDeclUnderlyingType() does not return anything useful. -// TODO: Fix the cursor's type or add new API in libclang for querying the template type alias. -TEST_F(ToolTipInfo, DISABLED_TypeName_ResolveTemplateTypeAlias) -{ - const ::ToolTipInfo actual = tooltip(124, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("Ptr<Nuu>")); -} - -TEST_F(ToolTipInfo, TypeName_ResolveTemplateTypeAlias_qdoc) -{ - ::ToolTipInfo expected; - expected.qdocIdCandidates = {Utf8StringLiteral("PtrFromTemplateTypeAlias")}; - expected.qdocMark = Utf8StringLiteral("PtrFromTemplateTypeAlias"); - expected.qdocCategory = ::ToolTipInfo::Typedef; - - const ::ToolTipInfo actual = tooltip(124, 5); - - ASSERT_THAT(actual, IsQdocToolTip(expected)); -} - -TEST_F(ToolTipInfo, TemplateClassReference) -{ - ::ToolTipInfo expected(Utf8StringLiteral("Zii<T>")); - expected.qdocIdCandidates = {Utf8StringLiteral("Zii")}; - expected.qdocMark = Utf8StringLiteral("Zii"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(134, 5); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, TemplateClassQualified) -{ - ::ToolTipInfo expected(Utf8StringLiteral("U::Yii<T>")); - expected.qdocIdCandidates = {Utf8StringLiteral("U::Yii"), Utf8StringLiteral("Yii")}; - expected.qdocMark = Utf8StringLiteral("Yii"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(135, 5); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, ResolveNamespaceAliasForType) -{ - ::ToolTipInfo expected(Utf8StringLiteral("A::X")); - expected.qdocIdCandidates = {Utf8StringLiteral("A::X"), Utf8StringLiteral("X")}; - expected.qdocMark = Utf8StringLiteral("X"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(144, 8); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -// TODO: Show unresolved and resolved name, for F1 try both. -TEST_F(ToolTipInfo, ResolveNamespaceAlias) -{ - ::ToolTipInfo expected(Utf8StringLiteral("A")); - expected.qdocIdCandidates = {Utf8StringLiteral("B")}; - expected.qdocMark = Utf8StringLiteral("B"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(144, 5); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, QualificationForTemplateClassInClassInNamespace) -{ - ::ToolTipInfo expected(Utf8StringLiteral("N::Outer::Inner<int>")); - expected.qdocIdCandidates = {Utf8StringLiteral("N::Outer::Inner"), - Utf8StringLiteral("Outer::Inner"), - Utf8StringLiteral("Inner")}; - expected.qdocMark = Utf8StringLiteral("Inner"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - expected.sizeInBytes = Utf8StringLiteral("1"); - - const ::ToolTipInfo actual = tooltip(153, 16); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, Function) -{ - ::ToolTipInfo expected(Utf8StringLiteral("void f()")); - expected.qdocIdCandidates = {Utf8StringLiteral("f")}; - expected.qdocMark = Utf8StringLiteral("f()"); - expected.qdocCategory = ::ToolTipInfo::Function; - - const ::ToolTipInfo actual = tooltip(165, 5); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -TEST_F(ToolTipInfo, Function_QualifiedName) -{ - const ::ToolTipInfo actual = tooltip(166, 8); - - ASSERT_THAT(actual.text, Utf8StringLiteral("void R::f()")); -} - -TEST_F(ToolTipInfo, Function_qdocIdCandidatesAreQualified) -{ - const ::ToolTipInfo actual = tooltip(166, 8); - - ASSERT_THAT(actual.qdocIdCandidates, ElementsAre(Utf8StringLiteral("R::f"), - Utf8StringLiteral("f"))); -} - -TEST_F(ToolTipInfo, Function_HasParameterName) -{ - const ::ToolTipInfo actual = tooltip(167, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("void f(int param)")); -} - -// TODO: Implement with CXPrintingPolicy -TEST_F(ToolTipInfo, DISABLED_Function_HasDefaultArgument) -{ - const ::ToolTipInfo actual = tooltip(168, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("void z(int = 1)")); -} - -TEST_F(ToolTipInfo, Function_qdocMarkHasNoParameterName) -{ - const ::ToolTipInfo actual = tooltip(167, 5); - - ASSERT_THAT(actual.qdocMark, Utf8StringLiteral("f(int)")); -} - -TEST_F(ToolTipInfo, Function_qdocMarkHasNoDefaultArgument) -{ - const ::ToolTipInfo actual = tooltip(168, 5); - - ASSERT_THAT(actual.qdocMark, Utf8StringLiteral("z(int)")); -} - -TEST_F(ToolTipInfo, AutoTypeBuiltin) -{ - const ::ToolTipInfo actual = tooltip(176, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("int")); -} - -TEST_F(ToolTipInfo, PointerToPointerToClass) -{ - ::ToolTipInfo expected(Utf8StringLiteral("Nuu **")); - expected.qdocIdCandidates = {Utf8StringLiteral("Nuu")}; - expected.qdocMark = Utf8StringLiteral("Nuu"); - expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; - - const ::ToolTipInfo actual = tooltip(200, 12); - - ASSERT_THAT(actual, IsToolTip(expected)); -} - -// TODO: Test for qdoc entries, too. -TEST_F(ToolTipInfo, AutoTypeEnum) -{ - const ::ToolTipInfo actual = tooltip(177, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("EnumType")); -} - -// TODO: Test for qdoc entries, too. -TEST_F(ToolTipInfo, AutoTypeClassType) -{ - const ::ToolTipInfo actual = tooltip(178, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("Bar")); -} - -// TODO: Test for qdoc entries, too. -// TODO: Deduced template arguments work, too?! -TEST_F(ToolTipInfo, AutoTypeClassTemplateType) -{ - const ::ToolTipInfo actual = tooltip(179, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("Zii<int>")); -} - -TEST_F(ToolTipInfo, Function_DefaultConstructor) -{ - const ::ToolTipInfo actual = tooltip(193, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("inline constexpr Con::Con() noexcept")); -} - -TEST_F(ToolTipInfo, Function_ExplicitDefaultConstructor) -{ - const ::ToolTipInfo actual = tooltip(194, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("ExplicitCon::ExplicitCon() noexcept = default")); -} - -TEST_F(ToolTipInfo, Function_CustomConstructor) -{ - const ::ToolTipInfo actual = tooltip(195, 5); - - ASSERT_THAT(actual.text, Utf8StringLiteral("ExplicitCon::ExplicitCon(int m)")); -} - -// Overloads are problematic for the help system since the data base has not -// enough information about them. At least for constructors we can improve -// the situation a bit - provide a help system query that: -// 1) will not lead to the replacement of the constructor signature as -// clang sees it with the wrong overload documentation -// (signature + main help sentence). That's the qdocCategory=Unknown -// part. -// 2) finds the documentation for the class instead of the overload, -// so F1 will go to the class documentation. -TEST_F(ToolTipInfo, Function_ConstructorQDoc) -{ - ::ToolTipInfo expected; - expected.qdocIdCandidates = {Utf8StringLiteral("Con")}; - expected.qdocMark = Utf8StringLiteral("Con"); - expected.qdocCategory = ::ToolTipInfo::Unknown; - - const ::ToolTipInfo actual = tooltip(193, 5); - - ASSERT_THAT(actual, IsQdocToolTip(expected)); -} - -std::unique_ptr<Data> ToolTipInfo::d; - -void ToolTipInfo::SetUpTestCase() -{ - d.reset(new Data); -} - -void ToolTipInfo::TearDownTestCase() -{ - d.reset(); -} - -} // anonymous namespace diff --git a/tests/unit/unittest/clangtranslationunit-test.cpp b/tests/unit/unittest/clangtranslationunit-test.cpp deleted file mode 100644 index 52fd447e98..0000000000 --- a/tests/unit/unittest/clangtranslationunit-test.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <clangtranslationunit.h> -#include <clangtranslationunitupdater.h> -#include <diagnosticcontainer.h> -#include <utf8string.h> - -#include <clang-c/Index.h> - -using ClangBackEnd::DiagnosticContainer; -using ClangBackEnd::TranslationUnit; -using ClangBackEnd::TranslationUnitUpdateInput; -using ClangBackEnd::TranslationUnitUpdateResult; - -using testing::ContainerEq; -using testing::Eq; - -namespace { - -class TranslationUnit : public ::testing::Test -{ -protected: - void SetUp() override; - void TearDown() override; - - void parse(); - void reparse(); - - DiagnosticContainer createDiagnostic(const QString &text, - ClangBackEnd::DiagnosticSeverity severity, - int line, - int column, - const QString &filePath) const; - QVector<DiagnosticContainer> diagnosticsFromMainFile() const; - QVector<DiagnosticContainer> errorDiagnosticsFromHeaders() const; - -protected: - Utf8String sourceFilePath = Utf8StringLiteral(TESTDATA_DIR"/diagnostic_erroneous_source.cpp"); - Utf8String headerFilePath = Utf8StringLiteral(TESTDATA_DIR"/diagnostic_erroneous_header.h"); - CXIndex cxIndex = nullptr; - CXTranslationUnit cxTranslationUnit = nullptr; - ::TranslationUnit translationUnit{Utf8String(), sourceFilePath, cxIndex, cxTranslationUnit}; - - DiagnosticContainer extractedFirstHeaderErrorDiagnostic; - QVector<DiagnosticContainer> extractedMainFileDiagnostics; -}; - -using TranslationUnitSlowTest = TranslationUnit; - -TEST_F(TranslationUnitSlowTest, HasExpectedMainFileDiagnostics) -{ - translationUnit.extractDiagnostics(extractedFirstHeaderErrorDiagnostic, - extractedMainFileDiagnostics); - - ASSERT_THAT(extractedMainFileDiagnostics, ContainerEq(diagnosticsFromMainFile())); -} - -TEST_F(TranslationUnitSlowTest, HasExpectedMainFileDiagnosticsAfterReparse) -{ - reparse(); - - translationUnit.extractDiagnostics(extractedFirstHeaderErrorDiagnostic, - extractedMainFileDiagnostics); - - ASSERT_THAT(extractedMainFileDiagnostics, ContainerEq(diagnosticsFromMainFile())); -} - -TEST_F(TranslationUnitSlowTest, HasErrorDiagnosticsInHeaders) -{ - translationUnit.extractDiagnostics(extractedFirstHeaderErrorDiagnostic, - extractedMainFileDiagnostics); - - ASSERT_THAT(extractedFirstHeaderErrorDiagnostic, - Eq(errorDiagnosticsFromHeaders().first())); -} - -TEST_F(TranslationUnitSlowTest, HasErrorDiagnosticsInHeadersAfterReparse) -{ - reparse(); - - translationUnit.extractDiagnostics(extractedFirstHeaderErrorDiagnostic, - extractedMainFileDiagnostics); - - ASSERT_THAT(extractedFirstHeaderErrorDiagnostic, - Eq(errorDiagnosticsFromHeaders().first())); -} - -void TranslationUnit::SetUp() -{ - parse(); -} - -void TranslationUnit::TearDown() -{ - clang_disposeTranslationUnit(cxTranslationUnit); - clang_disposeIndex(cxIndex); -} - -void TranslationUnit::parse() -{ - TranslationUnitUpdateInput parseInput; - parseInput.filePath = sourceFilePath; - parseInput.parseNeeded = true; - const TranslationUnitUpdateResult parseResult = translationUnit.update(parseInput); - ASSERT_TRUE(parseResult.hasParsed()); -} - -void TranslationUnit::reparse() -{ - TranslationUnitUpdateInput parseInput; - parseInput.filePath = sourceFilePath; - parseInput.reparseNeeded = true; - const TranslationUnitUpdateResult parseResult = translationUnit.update(parseInput); - ASSERT_TRUE(parseResult.hasReparsed()); -} - -DiagnosticContainer TranslationUnit::createDiagnostic(const QString &text, - ClangBackEnd::DiagnosticSeverity severity, - int line, - int column, - const QString &filePath) const -{ - return DiagnosticContainer( - text, - Utf8StringLiteral(""), - {}, - severity, - {filePath, line, column}, - {}, - {}, - {} - ); -} - -QVector<ClangBackEnd::DiagnosticContainer> TranslationUnit::diagnosticsFromMainFile() const -{ - return { - createDiagnostic( - QStringLiteral("warning: enumeration value 'Three' not handled in switch"), - ClangBackEnd::DiagnosticSeverity::Warning, - 7, - 13, - sourceFilePath), - createDiagnostic( - QStringLiteral("error: void function 'g' should not return a value"), - ClangBackEnd::DiagnosticSeverity::Error, - 15, - 5, - sourceFilePath), - createDiagnostic( - QStringLiteral("warning: using the result of an assignment as a condition without parentheses"), - ClangBackEnd::DiagnosticSeverity::Warning, - 21, - 11, - sourceFilePath), - }; -} - -QVector<ClangBackEnd::DiagnosticContainer> TranslationUnit::errorDiagnosticsFromHeaders() const -{ - return { - createDiagnostic( - QStringLiteral("error: C++ requires a type specifier for all declarations"), - ClangBackEnd::DiagnosticSeverity::Error, - 11, - 1, - headerFilePath), - }; -} - -} // anonymous namespace diff --git a/tests/unit/unittest/clangtranslationunits-test.cpp b/tests/unit/unittest/clangtranslationunits-test.cpp deleted file mode 100644 index acdf570481..0000000000 --- a/tests/unit/unittest/clangtranslationunits-test.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <clangbackend_global.h> -#include <clangexceptions.h> -#include <clangtranslationunit.h> -#include <clangtranslationunits.h> -#include <utf8string.h> - -#include <clang-c/Index.h> - -using ClangBackEnd::Clock; -using ClangBackEnd::TranslationUnit; -using ClangBackEnd::TranslationUnits; -using ClangBackEnd::TranslationUnitDoesNotExist; -using ClangBackEnd::PreferredTranslationUnit; - -using testing::Eq; - -namespace { - -class TranslationUnits : public ::testing::Test -{ -protected: - Utf8String someFilePath = Utf8StringLiteral("someFilePath"); - ClangBackEnd::TranslationUnits translationUnits{someFilePath}; -}; - -TEST_F(TranslationUnits, CreatedUnitIsNull) -{ - TranslationUnit translationUnit = translationUnits.createAndAppend(); - - ASSERT_TRUE(translationUnit.isNull()); -} - -TEST_F(TranslationUnits, GetThrowsForNotExisting) -{ - ASSERT_THROW(translationUnits.get(), TranslationUnitDoesNotExist); -} - -TEST_F(TranslationUnits, GetForSingleTranslationUnit) -{ - const TranslationUnit created = translationUnits.createAndAppend(); - - const TranslationUnit queried = translationUnits.get(); - - ASSERT_THAT(queried.id(), Eq(created.id())); -} - -TEST_F(TranslationUnits, GetFirstForMultipleTranslationUnits) -{ - const TranslationUnit created1 = translationUnits.createAndAppend(); - translationUnits.createAndAppend(); - - const TranslationUnit queried = translationUnits.get(); - - ASSERT_THAT(queried.id(), Eq(created1.id())); -} - -TEST_F(TranslationUnits, GetFirstForMultipleTranslationUnitsAndOnlyFirstParsed) -{ - const TranslationUnit created1 = translationUnits.createAndAppend(); - translationUnits.updateParseTimePoint(created1.id(), Clock::now()); - translationUnits.createAndAppend(); - - const TranslationUnit queried = translationUnits.get(); - - ASSERT_THAT(queried.id(), Eq(created1.id())); -} - -TEST_F(TranslationUnits, GetFirstForMultipleTranslationUnitsAndOnlySecondParsed) -{ - const TranslationUnit created1 = translationUnits.createAndAppend(); - const TranslationUnit created2 = translationUnits.createAndAppend(); - translationUnits.updateParseTimePoint(created2.id(), Clock::now()); - - const TranslationUnit queried = translationUnits.get(); - - ASSERT_THAT(queried.id(), Eq(created1.id())); -} - -TEST_F(TranslationUnits, GetLastUnitializedForMultipleTranslationUnits) -{ - const TranslationUnit created1 = translationUnits.createAndAppend(); - translationUnits.updateParseTimePoint(created1.id(), Clock::now()); - const TranslationUnit created2 = translationUnits.createAndAppend(); - - const TranslationUnit queried = translationUnits.get(PreferredTranslationUnit::LastUninitialized); - - ASSERT_THAT(queried.id(), Eq(created2.id())); -} - -TEST_F(TranslationUnits, GetRecentForMultipleTranslationUnits) -{ - const TranslationUnit created1 = translationUnits.createAndAppend(); - translationUnits.updateParseTimePoint(created1.id(), Clock::now()); - const TranslationUnit created2 = translationUnits.createAndAppend(); - translationUnits.updateParseTimePoint(created2.id(), Clock::now()); - - const TranslationUnit queried = translationUnits.get(PreferredTranslationUnit::RecentlyParsed); - - ASSERT_THAT(queried.id(), Eq(created2.id())); -} - -TEST_F(TranslationUnits, GetPreviousForMultipleTranslationUnits) -{ - const TranslationUnit created1 = translationUnits.createAndAppend(); - translationUnits.updateParseTimePoint(created1.id(), Clock::now()); - const TranslationUnit created2 = translationUnits.createAndAppend(); - translationUnits.updateParseTimePoint(created2.id(), Clock::now()); - - const TranslationUnit queried = translationUnits.get(PreferredTranslationUnit::PreviouslyParsed); - - ASSERT_THAT(queried.id(), Eq(created1.id())); -} - -TEST_F(TranslationUnits, UpdateThrowsForNotExisting) -{ - ClangBackEnd::TranslationUnits otherTranslationUnits{someFilePath}; - const TranslationUnit translationUnit = otherTranslationUnits.createAndAppend(); - - ASSERT_THROW(translationUnits.updateParseTimePoint(translationUnit.id(), Clock::now()), - TranslationUnitDoesNotExist); -} - -} // anonymous namespace diff --git a/tests/unit/unittest/clangupdateannotationsjob-test.cpp b/tests/unit/unittest/clangupdateannotationsjob-test.cpp deleted file mode 100644 index 79623619c1..0000000000 --- a/tests/unit/unittest/clangupdateannotationsjob-test.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "clangasyncjob-base.h" - -#include <clangupdateannotationsjob.h> - -using namespace ClangBackEnd; - -using testing::Not; -using testing::_; - -namespace { - -class UpdateAnnotationsJob : public ClangAsyncJobTest -{ -protected: - void SetUp() override { BaseSetUp(JobRequest::Type::UpdateAnnotations, job); } - -protected: - ClangBackEnd::UpdateAnnotationsJob job; -}; - -using UpdateAnnotationsJobSlowTest = UpdateAnnotationsJob; - -TEST_F(UpdateAnnotationsJob, PrepareAsyncRun) -{ - job.setContext(jobContext); - - ASSERT_TRUE(job.prepareAsyncRun()); -} - -TEST_F(UpdateAnnotationsJobSlowTest, RunAsync) -{ - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(UpdateAnnotationsJobSlowTest, SendAnnotations) -{ - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, annotations(_)).Times(1); - - job.runAsync(); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(UpdateAnnotationsJobSlowTest, DontSendAnnotationsIfDocumentWasClosed) -{ - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, annotations(_)).Times(0); - - job.runAsync(); - documents.remove({FileContainer{filePath}}); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(UpdateAnnotationsJobSlowTest, DontSendAnnotationsIfDocumentRevisionChanged) -{ - job.setContext(jobContextWithMockClient); - job.prepareAsyncRun(); - EXPECT_CALL(mockIpcClient, annotations(_)).Times(0); - - job.runAsync(); - documents.update({FileContainer(filePath, Utf8String(), true, 99)}); - - ASSERT_TRUE(waitUntilJobFinished(job)); -} - -TEST_F(UpdateAnnotationsJobSlowTest, UpdatesDependentFilePaths) -{ - const QSet<Utf8String> dependentOnFilesBefore = document.dependedFilePaths(); - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - ASSERT_TRUE(waitUntilJobFinished(job)); - - ASSERT_THAT(dependentOnFilesBefore, Not(document.dependedFilePaths())); -} - -TEST_F(UpdateAnnotationsJobSlowTest, UpdatesUnresolvedFilePaths) -{ - const QSet<Utf8String> unresolvedBefore = document.unresolvedFilePaths(); - job.setContext(jobContext); - job.prepareAsyncRun(); - - job.runAsync(); - ASSERT_TRUE(waitUntilJobFinished(job)); - - ASSERT_THAT(unresolvedBefore, Not(document.unresolvedFilePaths())); -} - -} // anonymous diff --git a/tests/unit/unittest/codecompleter-test.cpp b/tests/unit/unittest/codecompleter-test.cpp deleted file mode 100644 index 714d380260..0000000000 --- a/tests/unit/unittest/codecompleter-test.cpp +++ /dev/null @@ -1,680 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <codecompleter.h> -#include <clangdocument.h> -#include <filecontainer.h> -#include <clangdocuments.h> -#include <unsavedfiles.h> -#include <utf8stringvector.h> - -#include <QCoreApplication> -#include <QFile> -#include <QTemporaryDir> - -using ::testing::ElementsAreArray; -using ::testing::Contains; -using ::testing::AllOf; -using ::testing::Not; -using ::testing::PrintToString; - -using ClangBackEnd::CodeCompletion; -using ClangBackEnd::CodeCompletionChunk; -using ClangBackEnd::CodeCompleter; - -namespace { - -MATCHER_P2(IsCodeCompletion, text, completionKind, - std::string(negation ? "isn't" : "is") + " code completion with text " - + PrintToString(text) + " and kind " + PrintToString(completionKind) - ) -{ - if (arg.text != text) { - *result_listener << "text is " + PrintToString(arg.text) + " and not " + PrintToString(text); - return false; - } - - if (arg.completionKind != completionKind) { - *result_listener << "kind is " + PrintToString(arg.completionKind) + " and not " + PrintToString(completionKind); - return false; - } - - return true; -} - -MATCHER_P(IsOverloadCompletion, text, - std::string(negation ? "isn't" : "is") + " overload completion with text " + PrintToString(text)) -{ - Utf8String overloadName; - for (auto &chunk : arg.chunks) { - if (chunk.kind == CodeCompletionChunk::Text) { - overloadName = chunk.text; - break; - } - } - if (overloadName != text) { - *result_listener << "text is " + PrintToString(overloadName) + " and not " + PrintToString(text); - return false; - } - - if (arg.completionKind != CodeCompletion::FunctionOverloadCompletionKind) { - *result_listener << "kind is " + PrintToString(arg.completionKind) + " and not " + PrintToString(CodeCompletion::FunctionOverloadCompletionKind); - return false; - } - - return true; -} - -MATCHER(HasFixIts, "") -{ - return !arg.requiredFixIts.empty(); -} - -class CodeCompleter : public ::testing::Test -{ -protected: - void SetUp(); - void copyTargetHeaderToTemporaryIncludeDirecory(); - void copyChangedTargetHeaderToTemporaryIncludeDirecory(); - ClangBackEnd::CodeCompleter setupCompleter(const ClangBackEnd::FileContainer &fileContainer); - static Utf8String readFileContent(const QString &fileName); - -protected: - QTemporaryDir includeDirectory; - Utf8String includePathArgument{QStringLiteral("-I") + includeDirectory.path()}; - QString targetHeaderPath{includeDirectory.path() + QStringLiteral("/complete_target_header.h")}; - ClangBackEnd::FileContainer mainFileContainer{Utf8StringLiteral(TESTDATA_DIR - "/complete_completer_main.cpp"), - Utf8StringVector{includePathArgument}, - {}}; - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - ClangBackEnd::Document document; - QScopedPointer<ClangBackEnd::CodeCompleter> completer; - ClangBackEnd::FileContainer unsavedMainFileContainer{mainFileContainer.filePath, - {includePathArgument}, - {}, - readFileContent("/complete_completer_main_unsaved.cpp"), - true}; - ClangBackEnd::FileContainer unsavedTargetHeaderFileContainer{targetHeaderPath, - {includePathArgument}, - {}, - readFileContent("/complete_target_header_unsaved.h"), - true}; - - ClangBackEnd::FileContainer arrowFileContainer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_arrow.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_arrow.cpp"), - true - }; - ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withDotArrowCorrectionForPointer.cpp"), - true - }; - ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerBeforeTyping{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withDotArrowCorrectionForPointer_beforeTyping.cpp"), - true - }; - ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerAfterTyping{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withDotArrowCorrectionForPointer_afterTyping.cpp"), - true - }; - ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerInitial{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withDotArrowCorrectionForPointerInitial.cpp"), - true - }; - ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerUpdated{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withDotArrowCorrectionForPointerUpdated.cpp"), - true - }; - ClangBackEnd::FileContainer noDotArrowCorrectionForObjectFileContainer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForObject.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withNoDotArrowCorrectionForObject.cpp"), - true - }; - ClangBackEnd::FileContainer noDotArrowCorrectionForFloatFileContainer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForFloat.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withNoDotArrowCorrectionForFloat.cpp"), - true - }; - ClangBackEnd::FileContainer noDotArrowCorrectionForObjectWithArrowOperatortFileContainer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForObjectWithArrowOperator.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withNoDotArrowCorrectionForObjectWithArrowOperator.cpp"), - true - }; - ClangBackEnd::FileContainer noDotArrowCorrectionForDotDotFileContainer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForDotDot.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withNoDotArrowCorrectionForDotDot.cpp"), - true - }; - ClangBackEnd::FileContainer noDotArrowCorrectionForArrowDotFileContainer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForArrowDot.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withNoDotArrowCorrectionForArrowDot.cpp"), - true - }; - ClangBackEnd::FileContainer noDotArrowCorrectionForOnlyDotFileContainer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForOnlyDot.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withNoDotArrowCorrectionForOnlyDot.cpp"), - true - }; - ClangBackEnd::FileContainer noDotArrowCorrectionForColonColonFileContainer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForColonColon.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withNoDotArrowCorrectionForColonColon.cpp"), - true - }; - ClangBackEnd::FileContainer dotArrowCorrectionForForwardDeclaredClassPointer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForForwardDeclaredClassPointer.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withDotArrowCorrectionForForwardDeclaredClassPointer.cpp"), - true - }; - ClangBackEnd::FileContainer globalCompletionAfterForwardDeclaredClassPointer{ - Utf8StringLiteral(TESTDATA_DIR"/complete_withGlobalCompletionAfterForwardDeclaredClassPointer.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_withGlobalCompletionAfterForwardDeclaredClassPointer.cpp"), - true - }; - ClangBackEnd::FileContainer smartPointerCompletion{ - Utf8StringLiteral(TESTDATA_DIR"/complete_smartpointer.cpp"), - {includePathArgument}, - {}, - readFileContent("/complete_smartpointer.cpp"), - true - }; - ClangBackEnd::FileContainer completionsOrder{ - Utf8StringLiteral(TESTDATA_DIR"/completions_order.cpp"), - {includePathArgument}, - {}, - readFileContent("/completions_order.cpp"), - true - }; -}; - -using CodeCompleterSlowTest = CodeCompleter; - -Utf8String CodeCompleter::readFileContent(const QString &fileName) -{ - QFile readFileContentFile(QStringLiteral(TESTDATA_DIR) + fileName); - bool hasOpened = readFileContentFile.open(QIODevice::ReadOnly | QIODevice::Text); - - EXPECT_TRUE(hasOpened); - - return Utf8String::fromByteArray(readFileContentFile.readAll()); -} - -void CodeCompleter::copyTargetHeaderToTemporaryIncludeDirecory() -{ - QFile::remove(targetHeaderPath); - bool hasCopied = QFile::copy(QString::fromUtf8(TESTDATA_DIR "/complete_target_header.h"), - targetHeaderPath); - EXPECT_TRUE(hasCopied); -} - -void CodeCompleter::copyChangedTargetHeaderToTemporaryIncludeDirecory() -{ - QFile::remove(targetHeaderPath); - bool hasCopied = QFile::copy(QString::fromUtf8(TESTDATA_DIR "/complete_target_header_changed.h"), - targetHeaderPath); - EXPECT_TRUE(hasCopied); -} - -void CodeCompleter::SetUp() -{ - EXPECT_TRUE(includeDirectory.isValid()); - documents.create({mainFileContainer}); - document = documents.document(mainFileContainer); - completer.reset(new ClangBackEnd::CodeCompleter(document.translationUnit(), unsavedFiles)); - - copyTargetHeaderToTemporaryIncludeDirecory(); - document.parse(); -} - -TEST_F(CodeCompleterSlowTest, FunctionInUnsavedFile) -{ - unsavedFiles.createOrUpdate({unsavedMainFileContainer}); - documents.update({unsavedMainFileContainer}); - ClangBackEnd::CodeCompleter myCompleter(document.translationUnit(), unsavedFiles); - - ASSERT_THAT(myCompleter.complete(27, 1), - AllOf(Contains(IsCodeCompletion(Utf8StringLiteral("FunctionWithArguments"), - CodeCompletion::FunctionCompletionKind)), - Contains(IsCodeCompletion(Utf8StringLiteral("Function"), - CodeCompletion::FunctionCompletionKind)), - Contains(IsCodeCompletion(Utf8StringLiteral("UnsavedFunction"), - CodeCompletion::FunctionCompletionKind)), - Contains(IsCodeCompletion(Utf8StringLiteral("f"), - CodeCompletion::FunctionCompletionKind)), - Not(Contains(IsCodeCompletion(Utf8StringLiteral("SavedFunction"), - CodeCompletion::FunctionCompletionKind))))); -} - -TEST_F(CodeCompleterSlowTest, VariableInUnsavedFile) -{ - unsavedFiles.createOrUpdate({unsavedMainFileContainer}); - documents.update({unsavedMainFileContainer}); - ClangBackEnd::CodeCompleter myCompleter(document.translationUnit(), unsavedFiles); - - ASSERT_THAT(myCompleter.complete(27, 1), - Contains(IsCodeCompletion(Utf8StringLiteral("VariableInUnsavedFile"), - CodeCompletion::VariableCompletionKind))); -} - -TEST_F(CodeCompleterSlowTest, GlobalVariableInUnsavedFile) -{ - unsavedFiles.createOrUpdate({unsavedMainFileContainer}); - documents.update({unsavedMainFileContainer}); - ClangBackEnd::CodeCompleter myCompleter(document.translationUnit(), unsavedFiles); - - ASSERT_THAT(myCompleter.complete(27, 1), - Contains(IsCodeCompletion(Utf8StringLiteral("GlobalVariableInUnsavedFile"), - CodeCompletion::VariableCompletionKind))); -} - -TEST_F(CodeCompleterSlowTest, Macro) -{ - unsavedFiles.createOrUpdate({unsavedMainFileContainer}); - documents.update({unsavedMainFileContainer}); - ClangBackEnd::CodeCompleter myCompleter(document.translationUnit(), unsavedFiles); - - ASSERT_THAT(myCompleter.complete(27, 1), - Contains(IsCodeCompletion(Utf8StringLiteral("Macro"), - CodeCompletion::PreProcessorCompletionKind))); -} - -TEST_F(CodeCompleterSlowTest, Keyword) -{ - ASSERT_THAT(completer->complete(27, 1), - Contains(IsCodeCompletion(Utf8StringLiteral("switch"), - CodeCompletion::KeywordCompletionKind))); -} - -TEST_F(CodeCompleterSlowTest, FunctionInIncludedHeader) -{ - ASSERT_THAT(completer->complete(27, 1), - Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeader"), - CodeCompletion::FunctionCompletionKind))); -} - -TEST_F(CodeCompleterSlowTest, UniquePointerCompletion) -{ - auto myCompleter = setupCompleter(smartPointerCompletion); - - ASSERT_THAT(myCompleter.complete(59, 54, 59, 32), - Contains(IsOverloadCompletion(Utf8StringLiteral("Bar")))); -} - -TEST_F(CodeCompleterSlowTest, SharedPointerCompletion) -{ - auto myCompleter = setupCompleter(smartPointerCompletion); - - ASSERT_THAT(myCompleter.complete(60, 55, 60, 33), - Contains(IsOverloadCompletion(Utf8StringLiteral("Bar")))); -} - -TEST_F(CodeCompleterSlowTest, QSharedPointerCompletion) -{ - auto myCompleter = setupCompleter(smartPointerCompletion); - - ASSERT_THAT(myCompleter.complete(61, 60, 61, 32), - Contains(IsOverloadCompletion(Utf8StringLiteral("Bar")))); -} - -TEST_F(CodeCompleterSlowTest, FunctionInUnsavedIncludedHeader) -{ - unsavedFiles.createOrUpdate({unsavedTargetHeaderFileContainer}); - documents.create({unsavedTargetHeaderFileContainer}); - ClangBackEnd::CodeCompleter myCompleter(document.translationUnit(), unsavedFiles); - - ASSERT_THAT(myCompleter.complete(27, 1), - Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderUnsaved"), - CodeCompletion::FunctionCompletionKind))); -} - -TEST_F(CodeCompleterSlowTest, DISABLED_FunctionInChangedIncludedHeader) -{ - copyChangedTargetHeaderToTemporaryIncludeDirecory(); - - ASSERT_THAT(completer->complete(27, 1), - Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderChanged"), - CodeCompletion::FunctionCompletionKind))); -} - -TEST_F(CodeCompleterSlowTest, DISABLED_FunctionInChangedIncludedHeaderWithUnsavedContentInMainFile) // it's not that bad because we reparse anyway -{ - unsavedFiles.createOrUpdate({unsavedMainFileContainer}); - documents.update({unsavedMainFileContainer}); - ClangBackEnd::CodeCompleter myCompleter(document.translationUnit(), unsavedFiles); - - copyChangedTargetHeaderToTemporaryIncludeDirecory(); - - ASSERT_THAT(myCompleter.complete(27, 1), - Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderChanged"), - CodeCompletion::FunctionCompletionKind))); -} - -TEST_F(CodeCompleterSlowTest, ArrowCompletion) -{ - auto myCompleter = setupCompleter(arrowFileContainer); - - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 10); - - ASSERT_THAT(completions, - Contains(IsCodeCompletion(Utf8StringLiteral("member"), - CodeCompletion::VariableCompletionKind))); - ASSERT_THAT(completions, Not(Contains(HasFixIts()))); -} - -TEST_F(CodeCompleterSlowTest, DotToArrowCompletionForPointer) -{ - auto myCompleter = setupCompleter(dotArrowCorrectionForPointerFileContainer); - - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 9); - - ASSERT_THAT(completions, - Contains(IsCodeCompletion(Utf8StringLiteral("member"), - CodeCompletion::VariableCompletionKind))); - ASSERT_THAT(completions, Contains(HasFixIts())); -} - -TEST_F(CodeCompleterSlowTest, DotToArrowCompletionForPointerInOutdatedDocument) -{ - auto fileContainerBeforeTyping = dotArrowCorrectionForPointerFileContainerBeforeTyping; - documents.create({fileContainerBeforeTyping}); - unsavedFiles.createOrUpdate({fileContainerBeforeTyping}); - auto document = documents.document(fileContainerBeforeTyping.filePath); - document.parse(); - unsavedFiles.createOrUpdate({dotArrowCorrectionForPointerFileContainerAfterTyping}); - ClangBackEnd::CodeCompleter myCompleter(documents.document(dotArrowCorrectionForPointerFileContainerAfterTyping).translationUnit(), - unsavedFiles); - - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 9); - - ASSERT_THAT(completions, - Contains(IsCodeCompletion(Utf8StringLiteral("member"), - CodeCompletion::VariableCompletionKind))); - ASSERT_THAT(completions, Contains(HasFixIts())); -} - -TEST_F(CodeCompleterSlowTest, NoDotToArrowCompletionForObject) -{ - auto myCompleter = setupCompleter(noDotArrowCorrectionForObjectFileContainer); - - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 9); - - ASSERT_THAT(completions, - Contains(IsCodeCompletion(Utf8StringLiteral("member"), - CodeCompletion::VariableCompletionKind))); - ASSERT_THAT(completions, Not(Contains(HasFixIts()))); -} - -TEST_F(CodeCompleterSlowTest, NoDotToArrowCompletionForFloat) -{ - auto myCompleter = setupCompleter(noDotArrowCorrectionForFloatFileContainer); - - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(3, 18); - - ASSERT_TRUE(completions.isEmpty()); -} - -TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForObjectWithArrowOperator) -{ - auto myCompleter = setupCompleter(noDotArrowCorrectionForObjectWithArrowOperatortFileContainer); - - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(8, 9); - - ASSERT_THAT(completions, - Contains(IsCodeCompletion(Utf8StringLiteral("member"), - CodeCompletion::VariableCompletionKind))); - ASSERT_THAT(completions, Not(Contains(HasFixIts()))); -} - -TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForDotDot) -{ - auto myCompleter = setupCompleter(noDotArrowCorrectionForDotDotFileContainer); - - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 10); - - ASSERT_TRUE(completions.isEmpty()); -} - -TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForArrowDot) -{ - auto myCompleter = setupCompleter(noDotArrowCorrectionForArrowDotFileContainer); - - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 11); - - ASSERT_TRUE(completions.isEmpty()); -} - -TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForOnlyDot) -{ - auto myCompleter = setupCompleter(noDotArrowCorrectionForOnlyDotFileContainer); - - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 6); - - ASSERT_TRUE(completions.isEmpty()); -} - -TEST_F(CodeCompleterSlowTest, GlobalCompletionForSpaceAfterOnlyDot) -{ - auto myCompleter = setupCompleter(noDotArrowCorrectionForOnlyDotFileContainer); - - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 7); - ASSERT_THAT(completions, - Contains(IsCodeCompletion(Utf8StringLiteral("Foo"), - CodeCompletion::ClassCompletionKind))); -} - -TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForColonColon) -{ - auto myCompleter = setupCompleter(noDotArrowCorrectionForColonColonFileContainer); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(1, 7); - - ASSERT_THAT(completions, Not(Contains(HasFixIts()))); -} - -// Our workaround is not applicable with LLVM/Clang 10 anymore, so disable this test for that version. -// Luckily, the workaround is not needed anymore with LLVM/Clang 11. -TEST_F(CodeCompleterSlowTest, DISABLED_FOR_CLANG_10(NoGlobalCompletionAfterForwardDeclaredClassPointer)) -{ - auto myCompleter = setupCompleter(globalCompletionAfterForwardDeclaredClassPointer); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 10); - - ASSERT_TRUE(completions.isEmpty()); -} - -TEST_F(CodeCompleterSlowTest, GlobalCompletionAfterForwardDeclaredClassPointer) -{ - auto myCompleter = setupCompleter(globalCompletionAfterForwardDeclaredClassPointer); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(6, 4); - - ASSERT_EQ(completions.isEmpty(), CINDEX_VERSION_MINOR != 59); -} - -TEST_F(CodeCompleterSlowTest, ConstructorCompletionExists) -{ - auto myCompleter = setupCompleter(completionsOrder); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(8, 1); - - int constructorIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "Constructor" && codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind; - }); - - ASSERT_THAT(constructorIndex != -1, true); -} - -TEST_F(CodeCompleterSlowTest, ClassConstructorCompletionsOrder) -{ - auto myCompleter = setupCompleter(completionsOrder); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(8, 1); - - int classIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "Constructor" && codeCompletion.completionKind == CodeCompletion::ClassCompletionKind; - }); - int constructorIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "Constructor" && codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind; - }); - - ASSERT_THAT(classIndex < constructorIndex, true); -} - -TEST_F(CodeCompleterSlowTest, SharedPointerCompletionsOrder) -{ - auto myCompleter = setupCompleter(smartPointerCompletion); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(62, 11); - - int resetIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "reset"; - }); - int barDestructorIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "~Bar"; - }); - - ASSERT_THAT(barDestructorIndex < resetIndex, true); -} - -TEST_F(CodeCompleterSlowTest, ConstructorHasOverloadCompletions) -{ - auto myCompleter = setupCompleter(completionsOrder); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(8, 1); - - int constructorsCount = Utils::count(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "Constructor" && codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind; - }); - - ASSERT_THAT(constructorsCount, 2); -} - -TEST_F(CodeCompleterSlowTest, FunctionOverloadsNoParametersOrder) -{ - auto myCompleter = setupCompleter(completionsOrder); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(27, 7); - - const int fooCount = Utils::count(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "foo"; - }); - - ASSERT_THAT(fooCount, 1); -} - -TEST_F(CodeCompleterSlowTest, FunctionOverloadsWithParametersOrder) -{ - auto myCompleter = setupCompleter(completionsOrder); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(27, 7); - - int firstIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "bar"; - }); - int secondIndex = Utils::indexOf(completions, [i = 0, firstIndex](const CodeCompletion &codeCompletion) mutable { - return (i++) > firstIndex && codeCompletion.text == "bar"; - }); - - ASSERT_THAT(abs(firstIndex - secondIndex), 1); -} - -TEST_F(CodeCompleterSlowTest, FunctionOverloadsWithoutDotOrArrowOrder) -{ - auto myCompleter = setupCompleter(completionsOrder); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(21, 1); - - int firstIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "bar"; - }); - int secondIndex = Utils::indexOf(completions, [i = 0, firstIndex](const CodeCompletion &codeCompletion) mutable { - return (i++) > firstIndex && codeCompletion.text == "bar"; - }); - - ASSERT_THAT(abs(firstIndex - secondIndex), 1); -} - -TEST_F(CodeCompleterSlowTest, LexicographicalSorting) -{ - auto myCompleter = setupCompleter(completionsOrder); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(40, 18); - - const int funcAIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "memberFuncAAA"; - }); - const int funcBIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "memberFuncBB"; - }); - const int funcCIndex = Utils::indexOf(completions, [](const CodeCompletion &codeCompletion) { - return codeCompletion.text == "memberFuncC"; - }); - - ASSERT_NE(funcAIndex, -1); - ASSERT_EQ(funcBIndex, funcAIndex + 1); - ASSERT_EQ(funcCIndex, funcAIndex + 2); -} - -ClangBackEnd::CodeCompleter CodeCompleter::setupCompleter( - const ClangBackEnd::FileContainer &fileContainer) -{ - documents.create({fileContainer}); - unsavedFiles.createOrUpdate({fileContainer}); - document = documents.document(fileContainer); - document.parse(); - - ClangBackEnd::Document document = documents.document(fileContainer); - return ClangBackEnd::CodeCompleter(document.translationUnit(), - unsavedFiles); -} - -} diff --git a/tests/unit/unittest/codecompletionsextractor-test.cpp b/tests/unit/unittest/codecompletionsextractor-test.cpp deleted file mode 100644 index 25c83cd14c..0000000000 --- a/tests/unit/unittest/codecompletionsextractor-test.cpp +++ /dev/null @@ -1,865 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "unittest-utility-functions.h" - -#include <clangcodecompleteresults.h> -#include <clangdocument.h> -#include <clangfilepath.h> -#include <codecompletionsextractor.h> -#include <filecontainer.h> -#include <clangunsavedfilesshallowarguments.h> -#include <clangtranslationunit.h> -#include <clangdocuments.h> -#include <unsavedfiles.h> -#include <utf8stringvector.h> - -#include <clang-c/Index.h> - -#include <QFile> - -using ClangBackEnd::CodeCompletionsExtractor; -using ClangBackEnd::ClangCodeCompleteResults; -using ClangBackEnd::FilePath; -using ClangBackEnd::Document; -using ClangBackEnd::CodeCompletion; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::UnsavedFilesShallowArguments; -using ClangBackEnd::CodeCompletionChunk; -using ClangBackEnd::CodeCompletionChunks; - -namespace { - -using ::testing::PrintToString; -using ::testing::Not; - -MATCHER_P3(HasCompletion, name, kind, availability, - std::string(negation ? "hasn't" : "has") + " completion of name " + PrintToString(name) + - ", kind " + PrintToString(kind)) -{ - ::CodeCompletionsExtractor &extractor = const_cast<::CodeCompletionsExtractor&>(arg); - while (extractor.next()) { - if (extractor.currentCodeCompletion().text == name) { - if (extractor.currentCodeCompletion().completionKind == kind) { - if (extractor.currentCodeCompletion().availability == availability) { - return true; - } else if (!extractor.peek(name)) { - *result_listener << "availability is " << PrintToString(extractor.currentCodeCompletion().availability) << " and not " << PrintToString(availability); - return false; - } - } else if (!extractor.peek(name)) { - *result_listener << "kind is " << PrintToString(extractor.currentCodeCompletion().completionKind) << " and not " << PrintToString(kind); - return false; - } - } - } - - return false; -} - -MATCHER_P2(HasCompletionChunks, name, chunks, - std::string(negation ? "hasn't" : "has") + " completion of name " + PrintToString(name) + - " with the chunks " + PrintToString(chunks)) -{ - ::CodeCompletionsExtractor &extractor = const_cast<::CodeCompletionsExtractor&>(arg); - while (extractor.next()) { - if (extractor.currentCodeCompletion().text == name) { - if (extractor.currentCodeCompletion().chunks == chunks) { - return true; - } else if (!extractor.peek(name)) { - *result_listener << "chunks are " << PrintToString(arg.currentCodeCompletion().chunks) << " and not " << PrintToString(chunks); - return false; - } - } - } - - return false; -} - -MATCHER_P2(HasBriefComment, name, briefComment, - std::string(negation ? "hasn't" : "has") + " completion of name " + PrintToString(name) + - " with the brief comment " + PrintToString(briefComment)) -{ - ::CodeCompletionsExtractor &extractor = const_cast<::CodeCompletionsExtractor&>(arg); - while (extractor.next()) { - if (extractor.currentCodeCompletion().text == name) { - if (extractor.currentCodeCompletion().briefComment == briefComment) { - return true; - } else if (!extractor.peek(name)) { - *result_listener << "briefComment is " << PrintToString(arg.currentCodeCompletion().briefComment) << " and not " << PrintToString(briefComment); - return false; - } - } - } - - return false; -} - - -const Utf8String unsavedFileContent(const char *unsavedFilePath) -{ - QFile unsavedFileContentFile(QString::fromUtf8(unsavedFilePath)); - bool isOpen = unsavedFileContentFile.open(QIODevice::ReadOnly | QIODevice::Text); - if (!isOpen) - ADD_FAILURE() << "File with the unsaved content cannot be opened!"; - - return Utf8String::fromByteArray(unsavedFileContentFile.readAll()); -} - -const ClangBackEnd::FileContainer unsavedDataFileContainer(const char *filePath, - const char *unsavedFilePath) -{ - return ClangBackEnd::FileContainer(Utf8String::fromUtf8(filePath), - unsavedFileContent(unsavedFilePath), - true); -} - -class CodeCompletionsExtractor : public ::testing::Test -{ -protected: - ClangCodeCompleteResults getResults(const Document &document, - uint line, - uint column = 1, - bool needsReparse = false); - -protected: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Utf8StringVector compilationArguments{UnitTest::addPlatformArguments()}; - Document functionDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_function.cpp"), compilationArguments, {}, documents}; - Document functionOverloadDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_functionoverload.cpp"), compilationArguments, {}, documents}; - Document variableDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_variable.cpp"), compilationArguments, {}, documents}; - Document classDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_class.cpp"), compilationArguments, {}, documents}; - Document namespaceDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_namespace.cpp"), compilationArguments, {}, documents}; - Document enumerationDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_enumeration.cpp"), compilationArguments, {}, documents}; - Document constructorDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_constructor.cpp"), compilationArguments, {}, documents}; - Document constructorMemberInitDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_constructorMemberInitialization.cpp"), compilationArguments, {}, documents}; - Document briefCommentDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_brief_comment.cpp"), compilationArguments, {}, documents}; - Document privateFunctionDefinitionDocument{Utf8StringLiteral(TESTDATA_DIR"/complete_extractor_private_function_definition.cpp"), compilationArguments, {}, documents}; -}; - -using CodeCompletionsExtractorSlowTest = CodeCompletionsExtractor; - -TEST_F(CodeCompletionsExtractorSlowTest, Function) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Function"), - CodeCompletion::FunctionCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, TemplateFunction) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("TemplateFunction"), - CodeCompletion::TemplateFunctionCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Variable) -{ - ClangCodeCompleteResults completeResults(getResults(variableDocument, 4)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(variableDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Var"), - CodeCompletion::VariableCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, NonTypeTemplateParameter) -{ - ClangCodeCompleteResults completeResults(getResults(variableDocument, 25, 19)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(variableDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("NonTypeTemplateParameter"), - CodeCompletion::VariableCompletionKind, - CodeCompletion::Available)); -} - - -TEST_F(CodeCompletionsExtractorSlowTest, VariableReference) -{ - ClangCodeCompleteResults completeResults(getResults(variableDocument, 12)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(variableDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Var"), - CodeCompletion::VariableCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Parameter) -{ - ClangCodeCompleteResults completeResults(getResults(variableDocument, 4)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(variableDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Parameter"), - CodeCompletion::VariableCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Field) -{ - ClangCodeCompleteResults completeResults(getResults(variableDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(variableDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Field"), - CodeCompletion::VariableCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Class) -{ - ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(classDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Class"), - CodeCompletion::ClassCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Struct) -{ - ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(classDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Struct"), - CodeCompletion::ClassCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Union) -{ - ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(classDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Union"), - CodeCompletion::ClassCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Typedef) -{ - ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(classDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("TypeDef"), - CodeCompletion::TypeAliasCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, UsingAsTypeAlias) -{ - ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(classDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("UsingClass"), - CodeCompletion::TypeAliasCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, TemplateTypeParameter) -{ - ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(classDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("TemplateTypeParameter"), - CodeCompletion::ClassCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, TemplateClass) -{ - ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(classDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("TemplateClass"), - CodeCompletion::TemplateClassCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, TemplateTemplateParameter) -{ - ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(classDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("TemplateTemplateParameter"), - CodeCompletion::TemplateClassCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, ClassTemplatePartialSpecialization) -{ - ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(classDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("ClassTemplatePartialSpecialization"), - CodeCompletion::TemplateClassCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Namespace) -{ - ClangCodeCompleteResults completeResults(getResults(namespaceDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(namespaceDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Namespace"), - CodeCompletion::NamespaceCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, NamespaceAlias) -{ - ClangCodeCompleteResults completeResults(getResults(namespaceDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(namespaceDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("NamespaceAlias"), - CodeCompletion::NamespaceCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Enumeration) -{ - ClangCodeCompleteResults completeResults(getResults(enumerationDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(enumerationDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Enumeration"), - CodeCompletion::EnumerationCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Enumerator) -{ - ClangCodeCompleteResults completeResults(getResults(enumerationDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(enumerationDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Enumerator"), - CodeCompletion::EnumeratorCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Constructor) -{ - ClangCodeCompleteResults completeResults(getResults(constructorDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(constructorDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Constructor"), - CodeCompletion::ConstructorCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, ConstructorMemberInitializer) { - ClangCodeCompleteResults completeResults(getResults(constructorMemberInitDocument, 2, 18)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(constructorDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, - HasCompletion(Utf8StringLiteral("member"), - CodeCompletion::VariableCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Destructor) -{ - ClangCodeCompleteResults completeResults(getResults(constructorDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(constructorDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("~Constructor"), - CodeCompletion::DestructorCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Method) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Method"), - CodeCompletion::FunctionDefinitionCompletionKind, - CodeCompletion::Available)); - ASSERT_FALSE(extractor.currentCodeCompletion().hasParameters); -} - -TEST_F(CodeCompletionsExtractorSlowTest, MethodWithParameters) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("MethodWithParameters"), - CodeCompletion::FunctionDefinitionCompletionKind, - CodeCompletion::Available)); - ASSERT_TRUE(extractor.currentCodeCompletion().hasParameters); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Slot) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Slot"), - CodeCompletion::SlotCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, Signal) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Signal"), - CodeCompletion::SignalCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, MacroDefinition) -{ - ClangCodeCompleteResults completeResults(getResults(variableDocument, 35)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(variableDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("MacroDefinition"), - CodeCompletion::PreProcessorCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, FunctionMacro) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("FunctionMacro"), - CodeCompletion::FunctionCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, IntKeyword) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("int"), - CodeCompletion::KeywordCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, SwitchKeyword) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("switch"), - CodeCompletion::KeywordCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, ClassKeyword) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("class"), - CodeCompletion::KeywordCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, DeprecatedFunction) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("DeprecatedFunction"), - CodeCompletion::FunctionDefinitionCompletionKind, - CodeCompletion::Deprecated)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, NotAccessibleFunction) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - // Availability should be NotAccessible, but see QTCREATORBUG-25244. - // It's better to offer completion for some non-accessible functions than - // not to offer completion for some accessible ones. - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("NotAccessibleFunction"), - CodeCompletion::FunctionDefinitionCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, NotAvailableFunction) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("NotAvailableFunction"), - CodeCompletion::FunctionDefinitionCompletionKind, - CodeCompletion::NotAvailable)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, UnsavedFile) -{ - Document document(Utf8String::fromUtf8(TESTDATA_DIR "/complete_extractor_function.cpp"), - compilationArguments, - {}, - documents); - unsavedFiles.createOrUpdate( - {unsavedDataFileContainer(TESTDATA_DIR "/complete_extractor_function.cpp", - TESTDATA_DIR "/complete_extractor_function_unsaved.cpp")}); - ClangCodeCompleteResults completeResults(getResults(document, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(document.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Method2"), - CodeCompletion::FunctionDefinitionCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, ChangeUnsavedFile) -{ - Document document(Utf8String::fromUtf8(TESTDATA_DIR "/complete_extractor_function.cpp"), - compilationArguments, - {}, - documents); - unsavedFiles.createOrUpdate( - {unsavedDataFileContainer(TESTDATA_DIR "/complete_extractor_function.cpp", - TESTDATA_DIR "/complete_extractor_function_unsaved.cpp")}); - ClangCodeCompleteResults completeResults(getResults(document, 20)); - unsavedFiles.createOrUpdate({unsavedDataFileContainer(TESTDATA_DIR"/complete_extractor_function.cpp", - TESTDATA_DIR"/complete_extractor_function_unsaved_2.cpp")}); - completeResults = getResults(document, 20); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(document.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Method3"), - CodeCompletion::FunctionDefinitionCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, ArgumentDefinition) -{ - Document variableDocument{Utf8StringLiteral(TESTDATA_DIR "/complete_extractor_variable.cpp"), - {Utf8StringLiteral("-DArgumentDefinition"), - Utf8StringLiteral("-std=gnu++14")}, - {}, - documents}; - ClangCodeCompleteResults completeResults(getResults(variableDocument, 35)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(variableDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("ArgumentDefinitionVariable"), - CodeCompletion::VariableCompletionKind, - CodeCompletion::Available)); -} - -TEST_F(CodeCompletionsExtractorSlowTest, NoArgumentDefinition) -{ - Document variableDocument{Utf8StringLiteral(TESTDATA_DIR "/complete_extractor_variable.cpp"), - {Utf8StringLiteral("-std=gnu++14")}, - {}, - documents}; - ClangCodeCompleteResults completeResults(getResults(variableDocument, 35)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(variableDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, Not(HasCompletion(Utf8StringLiteral("ArgumentDefinitionVariable"), - CodeCompletion::VariableCompletionKind, - CodeCompletion::Available))); -} - -TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksFunction) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("Function"), - CodeCompletionChunks({{CodeCompletionChunk::ResultType, Utf8StringLiteral("void")}, - {CodeCompletionChunk::TypedText, Utf8StringLiteral("Function")}, - {CodeCompletionChunk::LeftParen, Utf8StringLiteral("(")}, - {CodeCompletionChunk::RightParen, Utf8StringLiteral(")")}}))); -} - -TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksFunctionWithOptionalChunks) -{ - ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("FunctionWithOptional"), - CodeCompletionChunks({{CodeCompletionChunk::ResultType, Utf8StringLiteral("void")}, - {CodeCompletionChunk::TypedText, Utf8StringLiteral("FunctionWithOptional")}, - {CodeCompletionChunk::LeftParen, Utf8StringLiteral("(")}, - {CodeCompletionChunk::Placeholder, Utf8StringLiteral("int x")}, - {CodeCompletionChunk::Comma, Utf8StringLiteral(", "), true}, - {CodeCompletionChunk::Placeholder, Utf8StringLiteral("char y = 1"), true}, - {CodeCompletionChunk::Comma, Utf8StringLiteral(", "), true}, - {CodeCompletionChunk::Placeholder, Utf8StringLiteral("int z = 5"), true}, - {CodeCompletionChunk::RightParen, Utf8StringLiteral(")")}}))); -} - -TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksField) -{ - ClangCodeCompleteResults completeResults(getResults(variableDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(variableDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("Field"), - CodeCompletionChunks({{CodeCompletionChunk::ResultType, Utf8StringLiteral("int")}, - {CodeCompletionChunk::TypedText, Utf8StringLiteral("Field")}}))); -} - -TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksEnumerator) -{ - ClangCodeCompleteResults completeResults(getResults(enumerationDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(enumerationDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("Enumerator"), - CodeCompletionChunks({{CodeCompletionChunk::ResultType, Utf8StringLiteral("Enumeration")}, - {CodeCompletionChunk::TypedText, Utf8StringLiteral("Enumerator")}}))); -} - -TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksEnumeration) -{ - ClangCodeCompleteResults completeResults(getResults(enumerationDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(enumerationDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("Enumeration"), - CodeCompletionChunks({{CodeCompletionChunk::TypedText, Utf8StringLiteral("Enumeration")}}))); -} - -TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksClass) -{ - ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(classDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("Class"), - CodeCompletionChunks({{CodeCompletionChunk::TypedText, Utf8StringLiteral("Class")}}))); -} - -TEST_F(CodeCompletionsExtractorSlowTest, BriefComment) -{ - ClangCodeCompleteResults completeResults(getResults(briefCommentDocument, 10, 1, - /*needsReparse=*/ true)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(briefCommentDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasBriefComment(Utf8StringLiteral("BriefComment"), Utf8StringLiteral("A brief comment"))); -} - -TEST_F(CodeCompletionsExtractorSlowTest, OverloadCandidate) -{ - ClangCodeCompleteResults completeResults(getResults(functionOverloadDocument, 8, 13)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(functionOverloadDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletionChunks(Utf8String(), - CodeCompletionChunks({ - {CodeCompletionChunk::Text, Utf8StringLiteral("Foo")}, - {CodeCompletionChunk::LeftParen, Utf8StringLiteral("(")}, - {CodeCompletionChunk::CurrentParameter, Utf8StringLiteral("const Foo &foo")}, - {CodeCompletionChunk::RightParen, Utf8StringLiteral(")")}, - }))); -} - -TEST_F(CodeCompletionsExtractorSlowTest, ExtractAll) -{ - ClangCodeCompleteResults completeResults(getResults(constructorDocument, 25)); - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(constructorDocument.filePath()), - completeResults.data()); - - auto codeCompletions = extractor.extractAll(false); - - ASSERT_THAT(codeCompletions.empty(), false); -} - -TEST_F(CodeCompletionsExtractorSlowTest, PrivateFunctionDefinition) -{ - ClangCodeCompleteResults completeResults(getResults(privateFunctionDefinitionDocument, 5, 12)); - - ::CodeCompletionsExtractor extractor( - unsavedFiles.unsavedFile(privateFunctionDefinitionDocument.filePath()), - completeResults.data()); - - ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("method"), - CodeCompletion::FunctionDefinitionCompletionKind, - CodeCompletion::Available)); -} - -ClangCodeCompleteResults CodeCompletionsExtractor::getResults(const Document &document, - uint line, - uint column, - bool needsReparse) -{ - document.parse(); - if (needsReparse) - document.reparse(); - - const Utf8String nativeFilePath = FilePath::toNativeSeparators(document.filePath()); - UnsavedFilesShallowArguments unsaved = unsavedFiles.shallowArguments(); - - return ClangCodeCompleteResults(clang_codeCompleteAt(document.translationUnit().cxTranslationUnit(), - nativeFilePath.constData(), - line, - column, - unsaved.data(), - unsaved.count(), - CXCodeComplete_IncludeMacros | CXCodeComplete_IncludeCodePatterns | CXCodeComplete_IncludeBriefComments)); -} - -} diff --git a/tests/unit/unittest/cursor-test.cpp b/tests/unit/unittest/cursor-test.cpp deleted file mode 100644 index 521002f3d2..0000000000 --- a/tests/unit/unittest/cursor-test.cpp +++ /dev/null @@ -1,941 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include "clangcompareoperators.h" -#include "unittest-utility-functions.h" - -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangstring.h> -#include <cursor.h> -#include <sourcelocation.h> -#include <sourcerange.h> -#include <clangtranslationunit.h> -#include <unsavedfiles.h> - -using ClangBackEnd::Cursor; -using ClangBackEnd::Document; -using ClangBackEnd::TranslationUnit; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::Documents; -using ClangBackEnd::ClangString; -using ClangBackEnd::SourceRange; - -using testing::IsNull; -using testing::NotNull; -using testing::Gt; -using testing::Contains; -using testing::EndsWith; -using testing::AllOf; -using testing::Not; -using testing::IsEmpty; -using testing::StrEq; -using testing::Eq; - -namespace { - -struct Data { - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/cursor.cpp")}; - Document document{filePath, - UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++11")}), - {}, - documents}; - TranslationUnit translationUnit{filePath, - filePath, - document.translationUnit().cxIndex(), - document.translationUnit().cxTranslationUnit()}; -}; - -class Cursor : public ::testing::Test -{ -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - -protected: - static Data *d; - const Document &document = d->document; - const TranslationUnit &translationUnit = d->translationUnit; -}; - - - -TEST_F(Cursor, CreateNullCursor) -{ - ::Cursor cursor; - - ASSERT_TRUE(cursor.isNull()); -} - -TEST_F(Cursor, CompareNullCursors) -{ - ::Cursor cursor; - ::Cursor cursor2; - - ASSERT_THAT(cursor, cursor2); -} - -TEST_F(Cursor, IsNotValid) -{ - ::Cursor cursor; - - ASSERT_FALSE(cursor.isValid()); -} - -TEST_F(Cursor, IsValid) -{ - auto cursor = translationUnit.cursor(); - - ASSERT_TRUE(cursor.isValid()); -} - -TEST_F(Cursor, IsTranslationUnit) -{ - auto cursor = translationUnit.cursor(); - - ASSERT_TRUE(cursor.isTranslationUnit()); -} - -TEST_F(Cursor, NullCursorIsNotTranslationUnit) -{ - ::Cursor cursor; - - ASSERT_FALSE(cursor.isTranslationUnit()); -} - -TEST_F(Cursor, UnifiedSymbolResolution) -{ - ::Cursor cursor; - - ASSERT_FALSE(cursor.unifiedSymbolResolution().hasContent()); -} - -TEST_F(Cursor, GetCursorAtLocation) -{ - auto cursor = translationUnit.cursorAt(3, 6); - - ASSERT_THAT(cursor.unifiedSymbolResolution(), Eq("c:@F@function#I#")); -} - -TEST_F(Cursor, GetCursoSourceLocation) -{ - auto cursor = translationUnit.cursorAt(3, 6); - - ASSERT_THAT(cursor.sourceLocation(), translationUnit.sourceLocationAt(3, 6)); -} - -TEST_F(Cursor, GetCursoSourceRange) -{ - auto cursor = translationUnit.cursorAt(3, 6); - - ASSERT_THAT(cursor.sourceRange(), SourceRange(translationUnit.sourceLocationAt(3, 1), - translationUnit.sourceLocationAt(6, 2))); -} - -TEST_F(Cursor, Mangling) -{ - auto cursor = translationUnit.cursorAt(3, 6); - - ASSERT_TRUE(cursor.mangling().hasContent()); -} - -TEST_F(Cursor, Spelling) -{ - auto cursor = translationUnit.cursorAt(3, 6); - - ASSERT_THAT(cursor.spelling().cString(), StrEq("function")); -} - -TEST_F(Cursor, DisplayName) -{ - auto cursor = translationUnit.cursorAt(3, 6); - - ASSERT_THAT(cursor.displayName(), Eq("function(int)")); -} - -TEST_F(Cursor, BriefComment) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7); - - ASSERT_THAT(cursor.briefComment(), Eq("A brief comment")); -} - -TEST_F(Cursor, RawComment) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7); - - ASSERT_THAT(cursor.rawComment(), Eq("/**\n * A brief comment\n */")); -} - -TEST_F(Cursor, CommentRange) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7); - - - ASSERT_THAT(cursor.commentRange(), - SourceRange(translationUnit.sourceLocationAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 7, 1), - translationUnit.sourceLocationAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 9, 4))); -} - -TEST_F(Cursor, IsDefinition) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7); - - ASSERT_TRUE(cursor.isDefinition()); -} - -TEST_F(Cursor, ForwardDeclarationIsNotDefinition) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 6, 7); - - ASSERT_FALSE(cursor.isDefinition()); -} - -TEST_F(Cursor, GetDefinitionOfFowardDeclaration) -{ - auto forwardDeclarationcursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 6, 7); - auto definitionCursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7); - - ASSERT_THAT(forwardDeclarationcursor.definition(), definitionCursor); -} - -TEST_F(Cursor, CallToMethodeIsNotDynamic) -{ - auto cursor = translationUnit.cursorAt(18, 5); - - ASSERT_FALSE(cursor.isDynamicCall()); -} - -TEST_F(Cursor, CallToAbstractVirtualMethodeIsDynamic) -{ - auto cursor = translationUnit.cursorAt(19, 5); - - ASSERT_TRUE(cursor.isDynamicCall()); -} - -TEST_F(Cursor, CanonicalCursor) -{ - auto forwardDeclarationcursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 6, 7); - auto definitionCursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7); - - ASSERT_THAT(definitionCursor.canonical(), forwardDeclarationcursor); -} - -TEST_F(Cursor, ReferencedCursor) -{ - auto functionCallCursor = translationUnit.cursorAt(18, 5); - auto functionCursor = translationUnit.cursorAt(16, 17); - - ASSERT_THAT(functionCallCursor.referenced(), functionCursor); -} - -TEST_F(Cursor, IsVirtual) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 15, 17); - - ASSERT_TRUE(cursor.isVirtualMethod()); -} - -TEST_F(Cursor, IsNotPureVirtualOnlyVirtual) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 15, 17); - - ASSERT_FALSE(cursor.isPureVirtualMethod()); -} - -TEST_F(Cursor, IsPureVirtual) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 16, 17); - - ASSERT_TRUE(cursor.isPureVirtualMethod()); -} - -TEST_F(Cursor, ConstantMethod) -{ - auto cursor = translationUnit.cursorAt(31, 18); - - ASSERT_TRUE(cursor.isConstantMethod()); -} - -TEST_F(Cursor, IsStaticMethod) -{ - auto cursor = translationUnit.cursorAt(36, 18); - - ASSERT_TRUE(cursor.isStaticMethod()); -} - -TEST_F(Cursor, TypeSpelling) -{ - auto cursor = translationUnit.cursorAt(43, 5); - - ASSERT_THAT(cursor.type().utf8Spelling(), Utf8StringLiteral("lint")); -} - -TEST_F(Cursor, CanonicalTypeSpelling) -{ - auto cursor = translationUnit.cursorAt(43, 5); - - ASSERT_THAT(cursor.type().canonical().utf8Spelling(), Utf8StringLiteral("long long")); -} - -TEST_F(Cursor, CanonicalTypeCStringSpelling) -{ - auto cursor = translationUnit.cursorAt(43, 5); - - auto spelling = cursor.type().canonical().spelling(); - - ASSERT_THAT(spelling.cString(), StrEq("long long")); -} - -TEST_F(Cursor, CanonicalTypeIsNotType) -{ - auto cursor = translationUnit.cursorAt(43, 5); - - ASSERT_THAT(cursor.type().canonical(), Not(cursor.type())); -} - -TEST_F(Cursor, TypeDeclartionIsAlias) -{ - auto declarationCursor = translationUnit.cursorAt(41, 5); - auto lintCursor = translationUnit.cursorAt(39, 11); - - ASSERT_THAT(declarationCursor.type().declaration().type(), lintCursor.type()); -} - -TEST_F(Cursor, TypeIsConstantWithoutAliasLookup) -{ - auto cursor = translationUnit.cursorAt(45, 16); - - ASSERT_TRUE(cursor.type().isConstant()); -} - -TEST_F(Cursor, ClassIsCompoundType) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 10, 7); - - ASSERT_TRUE(cursor.isCompoundType()); -} - -TEST_F(Cursor, StructIsCompoundType) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 28, 8); - - ASSERT_TRUE(cursor.isCompoundType()); -} - -TEST_F(Cursor, UnionIsCompoundType) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 33, 7); - - ASSERT_TRUE(cursor.isCompoundType()); -} - -TEST_F(Cursor, IsDeclaration) -{ - auto cursor = translationUnit.cursorAt(41, 10); - - ASSERT_TRUE(cursor.isDeclaration()); -} - -TEST_F(Cursor, SemanticParent) -{ - auto cursor = translationUnit.cursorAt(43, 6); - auto expectedSemanticParent = translationUnit.cursorAt(36, 18); - - auto semanticParent = cursor.semanticParent(); - - ASSERT_THAT(semanticParent, expectedSemanticParent); -} - -TEST_F(Cursor, IsLocalVariableInMethod) -{ - auto cursor = translationUnit.cursorAt(20, 9); - - ASSERT_TRUE(cursor.isLocalVariable()); -} - -TEST_F(Cursor, IsLocalVariableInStaticFunction) -{ - auto cursor = translationUnit.cursorAt(43, 5); - - ASSERT_TRUE(cursor.isLocalVariable()); -} - -TEST_F(Cursor, IsLocalVariableInTemplateFunction) -{ - auto cursor = translationUnit.cursorAt(52, 7); - - ASSERT_TRUE(cursor.isLocalVariable()); -} - -TEST_F(Cursor, IsLocalVariableInConversionOperator) -{ - auto cursor = translationUnit.cursorAt(57, 9); - - ASSERT_TRUE(cursor.isLocalVariable()); -} - -TEST_F(Cursor, IsLocalVariableInOperator) -{ - auto cursor = translationUnit.cursorAt(62, 9); - - ASSERT_TRUE(cursor.isLocalVariable()); -} - -TEST_F(Cursor, IsLocalVariableInConstructor) -{ - auto cursor = translationUnit.cursorAt(13, 9); - - ASSERT_TRUE(cursor.isLocalVariable()); -} - -TEST_F(Cursor, IsLocalVariableInDestructor) -{ - auto cursor = translationUnit.cursorAt(69, 9); - - ASSERT_TRUE(cursor.isLocalVariable()); -} - -TEST_F(Cursor, FindFunctionCaller) -{ - auto functionCursor = translationUnit.cursorAt(92, 24); - auto structCursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 28, 8); - - ASSERT_THAT(functionCursor.functionBaseDeclaration(), structCursor); -} - -TEST_F(Cursor, FindFunctionCallerPointer) -{ - auto functionCursor = translationUnit.cursorAt(79, 25); - auto structCursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 28, 8); - - ASSERT_THAT(functionCursor.functionBaseDeclaration(), structCursor); -} - -TEST_F(Cursor, FindFunctionCallerThis) -{ - auto functionCursor = translationUnit.cursorAt(106, 5); - auto structCursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 38, 8); - - ASSERT_THAT(functionCursor.functionBaseDeclaration(), structCursor); -} - -TEST_F(Cursor, NonPointerTypeForValue) -{ - auto variableCursor = translationUnit.cursorAt(101, 10); - auto variablePointerCursor = translationUnit.cursorAt(100, 11); - - ASSERT_THAT(variableCursor.nonPointerTupe(), variablePointerCursor.nonPointerTupe()); -} - -TEST_F(Cursor, HasFinalAttributeInFunction) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 30, 18); - - ASSERT_TRUE(cursor.hasFinalFunctionAttribute()); -} - -TEST_F(Cursor, HasNotFinalAttributeInFunction) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 15, 17); - - ASSERT_FALSE(cursor.hasFinalFunctionAttribute()); -} - -TEST_F(Cursor, HasFinalAttributeInClass) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 28, 8); - - ASSERT_TRUE(cursor.hasFinalClassAttribute()); -} - -TEST_F(Cursor, HasNotFinaAttributeInClass) -{ - auto cursor = translationUnit.cursorAt(Utf8StringLiteral(TESTDATA_DIR"/cursor.h"), 38, 8); - - ASSERT_FALSE(cursor.hasFinalClassAttribute()); -} - -TEST_F(Cursor, HasOutputValues) -{ - auto callExpressionCursor = translationUnit.cursorAt(117, 19); - auto outputArgumentExpectedSourceLocation = translationUnit.cursorAt(117, 20).cxSourceRange(); - - auto outputArgumentLocations = callExpressionCursor.outputArgumentRanges(); - - ASSERT_THAT(outputArgumentLocations.size(), 2); - ASSERT_THAT(outputArgumentLocations[0], outputArgumentExpectedSourceLocation); -} - -TEST_F(Cursor, HasOnlyInputValues) -{ - auto callExpressionCursor = translationUnit.cursorAt(118, 18); - - auto outputArgumentLocations = callExpressionCursor.outputArgumentRanges(); - - ASSERT_THAT(outputArgumentLocations, IsEmpty()); -} - -TEST_F(Cursor, ArgumentCountIsZero) -{ - auto cursor = translationUnit.cursorAt(121, 23); - - auto count = cursor.type().argumentCount(); - - ASSERT_THAT(count, 0); -} - -TEST_F(Cursor, ArgumentCountIsTwo) -{ - auto cursor = translationUnit.cursorAt(122, 22); - - auto count = cursor.type().argumentCount(); - - ASSERT_THAT(count, 2); -} - -TEST_F(Cursor, ArgumentOneIsValue) -{ - auto callExpressionCursor = translationUnit.cursorAt(122, 22); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isConstant()); - ASSERT_THAT(argument.kind(), CXType_Int); -} - -TEST_F(Cursor, ArgumentTwoIsLValueReference) -{ - auto callExpressionCursor = translationUnit.cursorAt(122, 22); - - auto argument = callExpressionCursor.type().argument(1); - - ASSERT_THAT(argument.kind(), CXType_LValueReference); -} - -TEST_F(Cursor, ArgumentTwoIsConstantReference) -{ - auto callExpressionCursor = translationUnit.cursorAt(122, 22); - - auto argumentPointee = callExpressionCursor.type().argument(1); - - ASSERT_TRUE(argumentPointee.isConstantReference()); -} - -TEST_F(Cursor, CursorArgumentCount) -{ - auto cursor = translationUnit.cursorAt(117, 19); - - ASSERT_THAT(cursor.kind(), CXCursor_CallExpr); - ASSERT_THAT(cursor.argumentCount(), 4); -} - -TEST_F(Cursor, CursorArgumentInputValue) -{ - auto callExpressionCursor = translationUnit.cursorAt(117, 19); - auto declarationReferenceExpressionCursor = translationUnit.cursorAt(117, 20); - - ASSERT_THAT(callExpressionCursor.argument(0), declarationReferenceExpressionCursor); -} - -TEST_F(Cursor, IsConstantLValueReference) -{ - auto callExpressionCursor = translationUnit.cursorAt(125, 26); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_TRUE(argument.isConstantReference()); -} - -TEST_F(Cursor, LValueReferenceIsNotConstantLValueReference) -{ - auto callExpressionCursor = translationUnit.cursorAt(124, 21); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isConstantReference()); -} - -TEST_F(Cursor, ValueIsNotConstantLValueReference) -{ - auto callExpressionCursor = translationUnit.cursorAt(123, 18); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isConstantReference()); -} - -TEST_F(Cursor, PointerToConstantNotConstantLValueReference) -{ - auto callExpressionCursor = translationUnit.cursorAt(126, 20); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isConstantReference()); -} - -TEST_F(Cursor, IsLValueReference) -{ - auto callExpressionCursor = translationUnit.cursorAt(124, 21); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_TRUE(argument.isLValueReference()); -} - -TEST_F(Cursor, ConstantLValueReferenceIsLValueReference) -{ - auto callExpressionCursor = translationUnit.cursorAt(125, 26); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_TRUE(argument.isLValueReference()); -} - -TEST_F(Cursor, ValueIsNotLValueReference) -{ - auto callExpressionCursor = translationUnit.cursorAt(123, 18); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isLValueReference()); -} - -TEST_F(Cursor, PointerIsNotLValueReference) -{ - auto callExpressionCursor = translationUnit.cursorAt(126, 20); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isLValueReference()); -} - -TEST_F(Cursor, PointerToConstant) -{ - auto callExpressionCursor = translationUnit.cursorAt(126, 20); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_TRUE(argument.isPointerToConstant()); -} - -TEST_F(Cursor, ValueIsNotPointerToConstant) -{ - auto callExpressionCursor = translationUnit.cursorAt(123, 18); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isPointerToConstant()); -} - -TEST_F(Cursor, PointerNotPointerToConstant) -{ - auto callExpressionCursor = translationUnit.cursorAt(127, 13); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isPointerToConstant()); -} - -TEST_F(Cursor, ConstantLValueReferenceIsNotPointerToConstant) -{ - auto callExpressionCursor = translationUnit.cursorAt(125, 26); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isPointerToConstant()); -} - -TEST_F(Cursor, IsConstantPointer) -{ - auto callExpressionCursor = translationUnit.cursorAt(128, 21); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_TRUE(argument.isConstantPointer()); -} - -TEST_F(Cursor, PointerToConstantIsNotConstantPointer) -{ - auto callExpressionCursor = translationUnit.cursorAt(126, 20); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isConstantPointer()); -} - -TEST_F(Cursor, ConstValueIsNotConstantPointer) -{ - auto callExpressionCursor = translationUnit.cursorAt(129, 23); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isConstantPointer()); -} - -TEST_F(Cursor, PointerToConstantIsReferencingConstant) -{ - auto callExpressionCursor = translationUnit.cursorAt(126, 20); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_TRUE(argument.isReferencingConstant()); -} - -TEST_F(Cursor, ConstantReferenceIsReferencingConstant) -{ - auto callExpressionCursor = translationUnit.cursorAt(125, 26); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_TRUE(argument.isReferencingConstant()); -} - -TEST_F(Cursor, LValueReferenceIsNotReferencingConstant) -{ - auto callExpressionCursor = translationUnit.cursorAt(124, 21); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isReferencingConstant()); -} - -TEST_F(Cursor, ValueIsNotReferencingConstant) -{ - auto callExpressionCursor = translationUnit.cursorAt(123, 18); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isReferencingConstant()); -} - -TEST_F(Cursor, PointerIsNotRefencingConstant) -{ - auto callExpressionCursor = translationUnit.cursorAt(127, 13); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isReferencingConstant()); -} - -TEST_F(Cursor, PointerIsOutputArgument) -{ - auto callExpressionCursor = translationUnit.cursorAt(127, 13); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_TRUE(argument.isOutputArgument()); -} - -TEST_F(Cursor, ConstantReferenceIsNotOutputArgument) -{ - auto callExpressionCursor = translationUnit.cursorAt(125, 26); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isOutputArgument()); -} - -TEST_F(Cursor, PointerToConstantIsNotOutputArgument) -{ - auto callExpressionCursor = translationUnit.cursorAt(126, 20); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isOutputArgument()) << argument.isConstant() << argument.pointeeType().isConstant(); -} - -TEST_F(Cursor, ConstantPointerIsOutputArgument) -{ - auto callExpressionCursor = translationUnit.cursorAt(128, 21); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_TRUE(argument.isOutputArgument()); -} - -TEST_F(Cursor, ReferenceIsOutputArgument) -{ - auto callExpressionCursor = translationUnit.cursorAt(124, 21); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_TRUE(argument.isOutputArgument()); -} - -TEST_F(Cursor, ConstReferenceIsNotOutputArgument) -{ - auto callExpressionCursor = translationUnit.cursorAt(125, 26); - - auto argument = callExpressionCursor.type().argument(0); - - ASSERT_FALSE(argument.isOutputArgument()); -} - -TEST_F(Cursor, ResultType) -{ - auto methodCursor = translationUnit.cursorAt(31, 18); - - Utf8String resultType = methodCursor.type().resultType().spelling(); - - ASSERT_THAT(resultType, Utf8String("bool", 4)); -} - -TEST_F(Cursor, PrivateMethodAccessSpecifier) -{ - auto methodCursor = translationUnit.cursorAt(16, 17); - - auto accessSpecifier = methodCursor.accessSpecifier(); - - ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Private); -} - -TEST_F(Cursor, PublicMethodAccessSpecifier) -{ - auto methodCursor = translationUnit.cursorAt(79, 25); - - auto accessSpecifier = methodCursor.accessSpecifier(); - - ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Public); -} - -TEST_F(Cursor, ProtectedMethodAccessSpecifier) -{ - auto methodCursor = translationUnit.cursorAt(131, 22); - - auto accessSpecifier = methodCursor.accessSpecifier(); - - ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Protected); -} - -TEST_F(Cursor, PrivateFieldAccessSpecifier) -{ - auto fieldCursor = translationUnit.cursorAt(21, 12); - - auto accessSpecifier = fieldCursor.accessSpecifier(); - - ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Private); -} - -TEST_F(Cursor, InvalidAccessSpecifier) -{ - auto localVarCursor = translationUnit.cursorAt(62, 9); - - auto accessSpecifier = localVarCursor.accessSpecifier(); - - ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Invalid); -} - -TEST_F(Cursor, NoStorageClass) -{ - auto localVarCursor = translationUnit.cursorAt(62, 9); - - auto storageClass = localVarCursor.storageClass(); - - ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::None); -} - -TEST_F(Cursor, ExternVarStorageClass) -{ - auto externalVarCursor = translationUnit.cursorAt(133, 12); - - auto storageClass = externalVarCursor.storageClass(); - - ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::Extern); -} - -TEST_F(Cursor, StaticMethodStorageClass) -{ - auto methodCursor = translationUnit.cursorAt(135, 13); - - auto storageClass = methodCursor.storageClass(); - - ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::Static); -} - -TEST_F(Cursor, InvalidStorageClass) -{ - auto functionTemplateCursor = translationUnit.cursorAt(137, 28); - - auto storageClass = functionTemplateCursor.storageClass(); - - ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::Invalid); -} - -TEST_F(Cursor, IsAnonymousNamespace) -{ - auto anonymousCursor = translationUnit.cursorAt(140, 1); - - bool anonymous = anonymousCursor.isAnonymous(); - - ASSERT_THAT(anonymous, true); -} - -TEST_F(Cursor, IsNotAnonymousNamespace) -{ - auto anonymousCursor = translationUnit.cursorAt(139, 1); - - bool anonymous = anonymousCursor.isAnonymous(); - - ASSERT_THAT(anonymous, false); -} - -TEST_F(Cursor, AnonymousNamespaceDisplayName) -{ - auto anonymousCursor = translationUnit.cursorAt(140, 1); - - auto name = anonymousCursor.displayName(); - - ASSERT_THAT(name, Utf8String("(anonymous)")); -} - -TEST_F(Cursor, AnonymousEnumDisplayName) -{ - auto anonymousCursor = translationUnit.cursorAt(144, 1); - - auto name = anonymousCursor.displayName(); - - ASSERT_THAT(name, Utf8String("(anonymous)")); -} - -Data *Cursor::d; - -void Cursor::SetUpTestCase() -{ - d = new Data; - d->document.parse(); -} - -void Cursor::TearDownTestCase() -{ - delete d; - d = nullptr; -} - -} diff --git a/tests/unit/unittest/diagnostic-test.cpp b/tests/unit/unittest/diagnostic-test.cpp deleted file mode 100644 index adfc503d3e..0000000000 --- a/tests/unit/unittest/diagnostic-test.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "diagnosticcontainer-matcher.h" -#include "googletest.h" -#include "rundocumentparse-utility.h" -#include "unittest-utility-functions.h" - -#include <diagnostic.h> -#include <diagnosticcontainer.h> -#include <diagnosticset.h> -#include <fixitcontainer.h> -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangtranslationunit.h> -#include <unsavedfiles.h> -#include <sourcelocation.h> -#include <sourcerange.h> - -#include <clang-c/Index.h> - - -using ::testing::Contains; -using ::testing::Not; -using ::testing::PrintToString; - -using ClangBackEnd::DiagnosticSet; -using ClangBackEnd::DiagnosticContainer; -using ClangBackEnd::Document; -using ClangBackEnd::Documents; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::Diagnostic; -using ClangBackEnd::SourceLocation; -using ClangBackEnd::DiagnosticSeverity; -using ClangBackEnd::FixItContainer; -using ClangBackEnd::SourceLocationContainer; - -namespace { - -MATCHER_P4(IsSourceLocation, filePath, line, column, offset, - std::string(negation ? "isn't" : "is") - + " source location with file path "+ PrintToString(filePath) - + ", line " + PrintToString(line) - + ", column " + PrintToString(column) - + " and offset " + PrintToString(offset) - ) -{ - if (!arg.filePath().endsWith(filePath) - || arg.line() != line - || arg.column() != column - || arg.offset() != offset) - return false; - - return true; -} - -class Diagnostic : public ::testing::Test -{ -protected: - enum ChildMode { WithChild, WithoutChild }; - - DiagnosticContainer expectedDiagnostic(ChildMode childMode) const; - -protected: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Document document{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_diagnostic.cpp"), - UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++11")}), - {}, - documents}; - UnitTest::RunDocumentParse _1{document}; - DiagnosticSet diagnosticSet{document.translationUnit().diagnostics()}; - ::Diagnostic diagnostic{diagnosticSet.front()}; -}; - -using DiagnosticSlowTest = Diagnostic; - -TEST_F(DiagnosticSlowTest, MoveContructor) -{ - const auto diagnostic2 = std::move(diagnostic); - - ASSERT_TRUE(diagnostic.isNull()); - ASSERT_FALSE(diagnostic2.isNull()); -} - -TEST_F(DiagnosticSlowTest, MoveAssigment) -{ - auto diagnostic2 = std::move(diagnostic); - diagnostic = std::move(diagnostic2); - - ASSERT_TRUE(diagnostic2.isNull()); - ASSERT_FALSE(diagnostic.isNull()); -} - -TEST_F(DiagnosticSlowTest, MoveSelfAssigment) -{ - diagnostic = std::move(diagnostic); - - ASSERT_FALSE(diagnostic.isNull()); -} - -TEST_F(DiagnosticSlowTest, Text) -{ -#if CINDEX_VERSION_MAJOR == 0 && CINDEX_VERSION_MINOR >= 59 // >= LLVM/Clang 10 - ASSERT_THAT(diagnostic.text(), Utf8StringLiteral("warning: non-void function does not return a value")); -#else - ASSERT_THAT(diagnostic.text(), Utf8StringLiteral("warning: control reaches end of non-void function")); -#endif -} - -TEST_F(DiagnosticSlowTest, Category) -{ - ASSERT_THAT(diagnostic.category(), Utf8StringLiteral("Semantic Issue")); -} - -TEST_F(DiagnosticSlowTest, EnableOption) -{ - ASSERT_THAT(diagnostic.options().first, Utf8StringLiteral("-Wreturn-type")); -} - -TEST_F(DiagnosticSlowTest, DisableOption) -{ - ASSERT_THAT(diagnostic.options().second, Utf8StringLiteral("-Wno-return-type")); -} - -TEST_F(DiagnosticSlowTest, Severity) -{ - ASSERT_THAT(diagnostic.severity(), DiagnosticSeverity::Warning); -} - -TEST_F(DiagnosticSlowTest, ChildDiagnosticsSize) -{ - auto diagnostic = diagnosticSet.back(); - - ASSERT_THAT(diagnostic.childDiagnostics().size(), 1); -} - -TEST_F(DiagnosticSlowTest, ChildDiagnosticsText) -{ - auto childDiagnostic = diagnosticSet.back().childDiagnostics().front(); - - ASSERT_THAT(childDiagnostic.text(), Utf8StringLiteral("note: candidate function not viable: requires 1 argument, but 0 were provided")); -} - -TEST_F(DiagnosticSlowTest, toDiagnosticContainerLetChildrenThroughByDefault) -{ - const auto diagnosticWithChild = expectedDiagnostic(WithChild); - - const auto diagnostic = diagnosticSet.back().toDiagnosticContainer(); - - ASSERT_THAT(diagnostic, IsDiagnosticContainer(diagnosticWithChild)); -} - -DiagnosticContainer Diagnostic::expectedDiagnostic(Diagnostic::ChildMode childMode) const -{ - QVector<DiagnosticContainer> children; - if (childMode == WithChild) { - const auto child = DiagnosticContainer( - Utf8StringLiteral("note: candidate function not viable: requires 1 argument, but 0 were provided"), - Utf8StringLiteral("Semantic Issue"), - {Utf8String(), Utf8String()}, - ClangBackEnd::DiagnosticSeverity::Note, - SourceLocationContainer(document.filePath(), 5, 6), - {}, - {}, - {} - ); - children.append(child); - } - - return - DiagnosticContainer( - Utf8StringLiteral("error: no matching function for call to 'f'"), - Utf8StringLiteral("Semantic Issue"), - {Utf8String(), Utf8String()}, - ClangBackEnd::DiagnosticSeverity::Error, - SourceLocationContainer(document.filePath(), 7, 5), - {}, - {}, - children - ); -} - -} diff --git a/tests/unit/unittest/diagnosticset-test.cpp b/tests/unit/unittest/diagnosticset-test.cpp deleted file mode 100644 index b59325e0e7..0000000000 --- a/tests/unit/unittest/diagnosticset-test.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "diagnosticcontainer-matcher.h" -#include "googletest.h" -#include "unittest-utility-functions.h" - -#include <clangsupport_global.h> -#include <clangdocument.h> -#include <diagnosticcontainer.h> -#include <diagnosticset.h> -#include <fixitcontainer.h> -#include <sourcelocation.h> -#include <sourcelocationcontainer.h> -#include <sourcerangecontainer.h> -#include <clangtranslationunit.h> -#include <clangdocuments.h> -#include <unsavedfiles.h> - -#include <clang-c/Index.h> - -using ::testing::Contains; -using ::testing::Not; -using ::testing::PrintToString; - -using ::ClangBackEnd::Diagnostic; -using ::ClangBackEnd::DiagnosticSet; -using ::ClangBackEnd::DiagnosticContainer; -using ::ClangBackEnd::FixItContainer; -using ::ClangBackEnd::SourceLocation; -using ::ClangBackEnd::SourceLocationContainer; -using ::ClangBackEnd::Document; -using ::ClangBackEnd::UnsavedFiles; - -namespace { - -const Utf8String headerFilePath = Utf8StringLiteral(TESTDATA_DIR"/diagnostic_diagnosticset_header.cpp"); - -class DiagnosticSet : public ::testing::Test -{ -protected: - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Utf8StringVector compilationArguments{ - UnitTest::addPlatformArguments({Utf8StringLiteral("-pedantic")})}; - Document document{Utf8StringLiteral(TESTDATA_DIR "/diagnostic_diagnosticset.cpp"), - compilationArguments, - {}, - documents}; - Document documentMainFile{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_diagnosticset_mainfile.cpp"), - compilationArguments, - {}, - documents}; - -protected: - enum ChildMode { WithChild, WithoutChild }; - DiagnosticContainer expectedDiagnostic(ChildMode childMode) const; -}; - -using DiagnosticSetSlowTest = DiagnosticSet; - -TEST_F(DiagnosticSetSlowTest, SetHasContent) -{ - document.parse(); - const auto set = document.translationUnit().diagnostics(); - - ASSERT_THAT(set.size(), 1); -} - -TEST_F(DiagnosticSetSlowTest, MoveConstructor) -{ - document.parse(); - auto set = document.translationUnit().diagnostics(); - - const auto set2 = std::move(set); - - ASSERT_TRUE(set.isNull()); - ASSERT_FALSE(set2.isNull()); -} - -TEST_F(DiagnosticSetSlowTest, MoveAssigment) -{ - document.parse(); - auto set = document.translationUnit().diagnostics(); - - auto set2 = std::move(set); - set = std::move(set2); - - ASSERT_TRUE(set2.isNull()); - ASSERT_FALSE(set.isNull()); -} - -TEST_F(DiagnosticSetSlowTest, MoveSelfAssigment) -{ - document.parse(); - auto set = document.translationUnit().diagnostics(); - - set = std::move(set); - - ASSERT_FALSE(set.isNull()); -} - -TEST_F(DiagnosticSetSlowTest, FirstElementEqualBegin) -{ - document.parse(); - auto set = document.translationUnit().diagnostics(); - - ASSERT_TRUE(set.front() == *set.begin()); -} - -TEST_F(DiagnosticSetSlowTest, BeginIsUnequalEnd) -{ - document.parse(); - auto set = document.translationUnit().diagnostics(); - - ASSERT_TRUE(set.begin() != set.end()); -} - -TEST_F(DiagnosticSetSlowTest, BeginPlusOneIsEqualEnd) -{ - document.parse(); - auto set = document.translationUnit().diagnostics(); - - ASSERT_TRUE(++set.begin() == set.end()); -} - -TEST_F(DiagnosticSetSlowTest, ToDiagnosticContainersLetThroughByDefault) -{ - const auto diagnosticContainerWithoutChild = expectedDiagnostic(WithChild); - documentMainFile.parse(); - - const auto diagnostics = documentMainFile.translationUnit().diagnostics().toDiagnosticContainers(); - - ASSERT_THAT(diagnostics, Contains(IsDiagnosticContainer(diagnosticContainerWithoutChild))); -} - -TEST_F(DiagnosticSetSlowTest, ToDiagnosticContainersFiltersOutTopLevelItem) -{ - documentMainFile.parse(); - const ::DiagnosticSet diagnosticSetWithChildren{documentMainFile.translationUnit().diagnostics()}; - const auto acceptNoDiagnostics = [](const Diagnostic &) { return false; }; - - const auto diagnostics = diagnosticSetWithChildren.toDiagnosticContainers(acceptNoDiagnostics); - - ASSERT_TRUE(diagnostics.isEmpty()); -} - -DiagnosticContainer DiagnosticSet::expectedDiagnostic(DiagnosticSet::ChildMode childMode) const -{ - QVector<DiagnosticContainer> children; - if (childMode == WithChild) { - const auto child = DiagnosticContainer( - Utf8StringLiteral("note: previous definition is here"), - Utf8StringLiteral("Semantic Issue"), - {Utf8String(), Utf8String()}, - ClangBackEnd::DiagnosticSeverity::Note, - SourceLocationContainer(headerFilePath, 1, 6), - {}, - {}, - {} - ); - children.append(child); - } - - return DiagnosticContainer( - Utf8StringLiteral("error: redefinition of 'f'"), - Utf8StringLiteral("Semantic Issue"), - {Utf8String(), Utf8String()}, - ClangBackEnd::DiagnosticSeverity::Error, - SourceLocationContainer(documentMainFile.filePath(), 3, 6), - {}, - {}, - children - ); -} - -} diff --git a/tests/unit/unittest/fixit-test.cpp b/tests/unit/unittest/fixit-test.cpp deleted file mode 100644 index 0d64107d09..0000000000 --- a/tests/unit/unittest/fixit-test.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "rundocumentparse-utility.h" - -#include <diagnostic.h> -#include <diagnosticset.h> -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangtranslationunit.h> -#include <unsavedfiles.h> -#include <sourcelocation.h> -#include <sourcerange.h> -#include <fixit.h> - -#include <clang-c/Index.h> - -using ClangBackEnd::DiagnosticSet; -using ClangBackEnd::Document; -using ClangBackEnd::TranslationUnit; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::Diagnostic; -using ClangBackEnd::FixIt; -using testing::PrintToString; - -namespace { - -MATCHER_P4(IsSourceLocation, filePath, line, column, offset, - std::string(negation ? "isn't" : "is") - + " source location with file path "+ PrintToString(filePath) - + ", line " + PrintToString(line) - + ", column " + PrintToString(column) - + " and offset " + PrintToString(offset) - ) -{ - if (!arg.filePath().endsWith(filePath) - || arg.line() != line - || arg.column() != column - || arg.offset() != offset) - return false; - - return true; -} - -struct Data -{ - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Document document{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_semicolon_fixit.cpp"), - {}, - {}, - documents}; - UnitTest::RunDocumentParse _1{document}; - TranslationUnit translationUnit{document.translationUnit()}; - DiagnosticSet diagnosticSet{translationUnit.diagnostics()}; - Diagnostic diagnostic{diagnosticSet.front()}; - ClangBackEnd::FixIt fixIt{diagnostic.fixIts().front()}; -}; - -class FixIt : public ::testing::Test -{ -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - -protected: - static std::unique_ptr<const Data> data; - const Diagnostic &diagnostic{data->diagnostic}; - const ClangBackEnd::FixIt &fixIt{data->fixIt}; -}; - -std::unique_ptr<const Data> FixIt::data; - -TEST_F(FixIt, Size) -{ - ASSERT_THAT(diagnostic.fixIts().size(), 1); -} - -TEST_F(FixIt, Text) -{ - ASSERT_THAT(fixIt.text(), Utf8StringLiteral(";")); -} - - -TEST_F(FixIt, DISABLED_ON_WINDOWS(Start)) -{ - ASSERT_THAT(fixIt.range().start(), IsSourceLocation(Utf8StringLiteral("diagnostic_semicolon_fixit.cpp"), - 3, - 13, - 29)); -} - -TEST_F(FixIt, DISABLED_ON_WINDOWS(End)) -{ - ASSERT_THAT(fixIt.range().end(), IsSourceLocation(Utf8StringLiteral("diagnostic_semicolon_fixit.cpp"), - 3, - 13, - 29)); -} - -void FixIt::SetUpTestCase() -{ - data = std::make_unique<const Data>(); -} - -void FixIt::TearDownTestCase() -{ - data.reset(); -} - -} // anonymous diff --git a/tests/unit/unittest/googletest.h b/tests/unit/unittest/googletest.h index 4c917a45b3..efc24cae96 100644 --- a/tests/unit/unittest/googletest.h +++ b/tests/unit/unittest/googletest.h @@ -42,9 +42,6 @@ #include "gtest-llvm-printing.h" #include "gtest-qt-printing.h" #include "gtest-std-printing.h" -#ifdef CLANG_UNIT_TESTS -# include "gtest-clang-printing.h" -#endif #include "google-using-declarations.h" diff --git a/tests/unit/unittest/gtest-clang-printing.cpp b/tests/unit/unittest/gtest-clang-printing.cpp deleted file mode 100644 index 00bb0d2e44..0000000000 --- a/tests/unit/unittest/gtest-clang-printing.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "gtest-creator-printing.h" -#include "gtest-std-printing.h" - -#ifdef CLANG_UNIT_TESTS -#include <clangdocumentsuspenderresumer.h> -#include <clangreferencescollector.h> -#include <fulltokeninfo.h> -#include <tokenprocessor.h> - -#endif - -#include <gtest/gtest-printers.h> - - -namespace ClangBackEnd { -std::ostream &operator<<(std::ostream &os, const TokenInfo &tokenInfo) -{ - os << "(type: " << tokenInfo.types() << ", " - << " line: " << tokenInfo.line() << ", " - << " column: " << tokenInfo.column() << ", " - << " length: " << tokenInfo.length() << ")"; - - return os; -} - -template<class T> -std::ostream &operator<<(std::ostream &out, const TokenProcessor<T> &tokenInfos) -{ - out << "["; - - for (const T &entry : tokenInfos) - out << entry; - - out << "]"; - - return out; -} - -template std::ostream &operator<<(std::ostream &out, const TokenProcessor<TokenInfo> &tokenInfos); -template std::ostream &operator<<(std::ostream &out, const TokenProcessor<FullTokenInfo> &tokenInfos); - -std::ostream &operator<<(std::ostream &out, const SuspendResumeJobsEntry &entry) -{ - return out << "(" << entry.document.filePath() << ", " << entry.jobRequestType << ", " - << entry.preferredTranslationUnit << ")"; -} - -std::ostream &operator<<(std::ostream &os, const ReferencesResult &value) -{ - os << "ReferencesResult("; - os << value.isLocalVariable << ", {"; - for (const SourceRangeContainer &r : value.references) { - os << r.start.line << ","; - os << r.start.column << ","; - os << r.end.column - r.start.column << ","; - } - os << "})"; - - return os; -} - -} // namespace ClangBackEnd diff --git a/tests/unit/unittest/gtest-clang-printing.h b/tests/unit/unittest/gtest-clang-printing.h deleted file mode 100644 index 4dfdbb2685..0000000000 --- a/tests/unit/unittest/gtest-clang-printing.h +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <iosfwd> - -#include <gtest/gtest-printers.h> - -namespace ClangBackEnd { -class TokenInfo; -template<typename T> -class TokenProcessor; -class SuspendResumeJobsEntry; -class ReferencesResult; - -std::ostream &operator<<(std::ostream &os, const TokenInfo &tokenInfo); -template<class T> -std::ostream &operator<<(std::ostream &out, const TokenProcessor<T> &tokenInfos); -std::ostream &operator<<(std::ostream &out, const SuspendResumeJobsEntry &entry); -std::ostream &operator<<(std::ostream &os, const ReferencesResult &value); - -} // namespace ClangBackEnd diff --git a/tests/unit/unittest/rundocumentparse-utility.h b/tests/unit/unittest/rundocumentparse-utility.h deleted file mode 100644 index 8bff06185d..0000000000 --- a/tests/unit/unittest/rundocumentparse-utility.h +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#pragma once - -#include <clangdocument.h> - -namespace UnitTest { - -struct RunDocumentParse { - RunDocumentParse(ClangBackEnd::Document &document) - { - document.parse(); - } -}; - -} // namespace UnitTest - diff --git a/tests/unit/unittest/skippedsourceranges-test.cpp b/tests/unit/unittest/skippedsourceranges-test.cpp deleted file mode 100644 index 6a2d80d852..0000000000 --- a/tests/unit/unittest/skippedsourceranges-test.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "unittest-utility-functions.h" - -#include <cursor.h> -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangstring.h> -#include <clangtranslationunit.h> -#include <skippedsourceranges.h> -#include <sourcelocation.h> -#include <sourcerange.h> -#include <unsavedfiles.h> - -#include <sourcerangecontainer.h> - -#include <QVector> - -using ClangBackEnd::Cursor; -using ClangBackEnd::Document; -using ClangBackEnd::Documents; -using ClangBackEnd::TranslationUnit; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::ClangString; -using ClangBackEnd::SourceRange; -using ClangBackEnd::SkippedSourceRanges; - -using testing::IsNull; -using testing::NotNull; -using testing::Gt; -using testing::Contains; -using testing::EndsWith; -using testing::AllOf; -using testing::Not; -using testing::IsEmpty; -using testing::SizeIs; -using testing::PrintToString; - -namespace { - -MATCHER_P4(IsSourceLocation, filePath, line, column, offset, - std::string(negation ? "isn't" : "is") - + " source location with file path "+ PrintToString(filePath) - + ", line " + PrintToString(line) - + ", column " + PrintToString(column) - + " and offset " + PrintToString(offset) - ) -{ - if (!arg.filePath().endsWith(filePath) - || arg.line() != line - || arg.column() != column - || arg.offset() != offset) { - return false; - } - - return true; -} - -struct Data { - Data() - { - document.parse(); - } - - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Utf8String filePath = Utf8StringLiteral(TESTDATA_DIR"/skippedsourceranges.cpp"); - Utf8StringVector compilationArguments{UnitTest::addPlatformArguments( - {Utf8StringLiteral("-std=c++11"), {}, Utf8StringLiteral("-DBLAH")})}; - Document document{filePath, compilationArguments, {}, documents}; - TranslationUnit translationUnit{filePath, - filePath, - document.translationUnit().cxIndex(), - document.translationUnit().cxTranslationUnit()}; -}; - -class SkippedSourceRanges : public ::testing::Test -{ -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - -protected: - static Data *d; - const TranslationUnit &translationUnit = d->translationUnit; - const Utf8String &filePath = d->filePath; - ::SkippedSourceRanges skippedSourceRanges{d->translationUnit.skippedSourceRanges()}; - ::SkippedSourceRanges otherSkippedSourceRanges{d->translationUnit.skippedSourceRanges()}; -}; - -Data *SkippedSourceRanges::d; - -TEST_F(SkippedSourceRanges, MoveConstructor) -{ - const auto other = std::move(skippedSourceRanges); - - ASSERT_TRUE(skippedSourceRanges.isNull()); - ASSERT_FALSE(other.isNull()); -} - -TEST_F(SkippedSourceRanges, MoveAssignment) -{ - skippedSourceRanges = std::move(otherSkippedSourceRanges); - - ASSERT_TRUE(otherSkippedSourceRanges.isNull()); - ASSERT_FALSE(skippedSourceRanges.isNull()); -} - -TEST_F(SkippedSourceRanges, RangeWithZero) -{ - auto ranges = skippedSourceRanges.sourceRanges(); - - ASSERT_THAT(ranges, SizeIs(2)); -} - -TEST_F(SkippedSourceRanges, DISABLED_ON_WINDOWS(RangeOne)) -{ - auto ranges = skippedSourceRanges.sourceRanges(); - - ASSERT_THAT(ranges[0].start(), IsSourceLocation(filePath, 2, 1, 6)); - ASSERT_THAT(ranges[0].end(), IsSourceLocation(filePath, 5, 1, 18)); -} - -TEST_F(SkippedSourceRanges, DISABLED_ON_WINDOWS(RangeTwo)) -{ - auto ranges = skippedSourceRanges.sourceRanges(); - - ASSERT_THAT(ranges[1].start(), IsSourceLocation(filePath, 8, 1, 39)); - ASSERT_THAT(ranges[1].end(), IsSourceLocation(filePath, 12, 1, 57)); -} - -TEST_F(SkippedSourceRanges, RangeContainerSize) -{ - auto ranges = skippedSourceRanges.toSourceRangeContainers(); - - ASSERT_THAT(ranges, SizeIs(2)); -} - -void SkippedSourceRanges::SetUpTestCase() -{ - d = new Data; -} - -void SkippedSourceRanges::TearDownTestCase() -{ - delete d; - d = nullptr; -} - -} diff --git a/tests/unit/unittest/sourcelocation-test.cpp b/tests/unit/unittest/sourcelocation-test.cpp deleted file mode 100644 index 3465682bf7..0000000000 --- a/tests/unit/unittest/sourcelocation-test.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "rundocumentparse-utility.h" - -#include <diagnostic.h> -#include <diagnosticset.h> -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangtranslationunit.h> -#include <unsavedfiles.h> -#include <sourcelocation.h> - -#include <utils/hostosinfo.h> - -#include <clang-c/Index.h> - -using ClangBackEnd::Diagnostic; -using ClangBackEnd::DiagnosticSet; -using ClangBackEnd::SourceLocation; -using ClangBackEnd::Document; -using ClangBackEnd::UnsavedFiles; - -using testing::EndsWith; -using testing::Not; - -namespace { - -struct Data { - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Document document{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_source_location.cpp"), - {}, - {}, - documents}; - UnitTest::RunDocumentParse _1{document}; - DiagnosticSet diagnosticSet{document.translationUnit().diagnostics()}; - Diagnostic diagnostic{diagnosticSet.front()}; - ClangBackEnd::SourceLocation sourceLocation{diagnostic.location()}; -}; - -class SourceLocation : public ::testing::Test -{ -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - -protected: - static std::unique_ptr<const Data> data; - const Document &document = data->document; - const ClangBackEnd::SourceLocation &sourceLocation = data->sourceLocation; -}; - -TEST_F(SourceLocation, FilePath) -{ - ASSERT_THAT(sourceLocation.filePath().constData(), EndsWith("diagnostic_source_location.cpp")); -} - -TEST_F(SourceLocation, Line) -{ - ASSERT_THAT(sourceLocation.line(), 4); -} - -TEST_F(SourceLocation, Column) -{ - ASSERT_THAT(sourceLocation.column(), 1); -} - -TEST_F(SourceLocation, Offset) -{ - ASSERT_THAT(sourceLocation.offset(), Utils::HostOsInfo::isWindowsHost() ? 21 : 18); -} - -TEST_F(SourceLocation, Create) -{ - ASSERT_THAT(document.translationUnit().sourceLocationAt(4, 1), sourceLocation); -} - -TEST_F(SourceLocation, NotEqual) -{ - ASSERT_THAT(document.translationUnit().sourceLocationAt(3, 1), Not(sourceLocation)); -} - -TEST_F(SourceLocation, BeforeMultibyteCharacter) -{ - ClangBackEnd::SourceLocation sourceLocation( - document.translationUnit().cxTranslationUnit(), - clang_getLocation(document.translationUnit().cxTranslationUnit(), - clang_getFile(document.translationUnit().cxTranslationUnit(), - document.filePath().constData()), - 8, 10)); - - ASSERT_THAT(document.translationUnit().sourceLocationAt(8, 10).column(), sourceLocation.column()); -} - -TEST_F(SourceLocation, AfterMultibyteCharacter) -{ - ClangBackEnd::SourceLocation sourceLocation( - document.translationUnit().cxTranslationUnit(), - clang_getLocation(document.translationUnit().cxTranslationUnit(), - clang_getFile(document.translationUnit().cxTranslationUnit(), - document.filePath().constData()), - 8, 12)); - - ASSERT_THAT(document.translationUnit().sourceLocationAt(8, 13).column(), sourceLocation.column()); -} - -std::unique_ptr<const Data> SourceLocation::data; - -void SourceLocation::SetUpTestCase() -{ - data = std::make_unique<const Data>(); -} - -void SourceLocation::TearDownTestCase() -{ - data.reset(); -} - -} diff --git a/tests/unit/unittest/sourcerange-test.cpp b/tests/unit/unittest/sourcerange-test.cpp deleted file mode 100644 index 26c7a5a422..0000000000 --- a/tests/unit/unittest/sourcerange-test.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "rundocumentparse-utility.h" -#include "unittest-utility-functions.h" - -#include <clangtranslationunit.h> -#include <diagnostic.h> -#include <diagnosticset.h> -#include <clangdocument.h> -#include <clangdocuments.h> -#include <unsavedfiles.h> -#include <sourcerange.h> - -#include <clang-c/Index.h> - -#include <memory> - -using ClangBackEnd::DiagnosticSet; -using ClangBackEnd::Document; -using ClangBackEnd::Documents; -using ClangBackEnd::TranslationUnit; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::Diagnostic; -using ClangBackEnd::SourceRange; - -using testing::PrintToString; -using testing::IsEmpty; - -namespace { - -MATCHER_P4(IsSourceLocation, filePath, line, column, offset, - std::string(negation ? "isn't" : "is") - + " source location with file path "+ PrintToString(filePath) - + ", line " + PrintToString(line) - + ", column " + PrintToString(column) - + " and offset " + PrintToString(offset) - ) -{ - if (!arg.filePath().endsWith(filePath) - || arg.line() != line - || arg.column() != column - || arg.offset() != offset) { - return false; - } - - return true; -} - -struct Data { - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/diagnostic_source_range.cpp")}; - Document document{filePath, - {UnitTest::addPlatformArguments({Utf8StringLiteral("-pedantic")})}, - {}, - documents}; - UnitTest::RunDocumentParse _1{document}; - TranslationUnit translationUnit{filePath, - filePath, - document.translationUnit().cxIndex(), - document.translationUnit().cxTranslationUnit()}; - DiagnosticSet diagnosticSet{document.translationUnit().diagnostics()}; - Diagnostic diagnostic{diagnosticSet.front()}; - Diagnostic diagnosticWithFilteredOutInvalidRange{diagnosticSet.at(1)}; - ClangBackEnd::SourceRange sourceRange{diagnostic.ranges().front()}; -}; - -class SourceRange : public ::testing::Test -{ -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - -protected: - static std::unique_ptr<const Data> data; - const ::SourceRange &sourceRange = data->sourceRange; - const Diagnostic &diagnostic = data->diagnostic; - const Diagnostic &diagnosticWithFilteredOutInvalidRange = data->diagnosticWithFilteredOutInvalidRange; - const TranslationUnit &translationUnit = data->translationUnit; -}; - -TEST_F(SourceRange, IsNull) -{ - ::SourceRange sourceRange; - - ASSERT_TRUE(sourceRange.isNull()); -} - -TEST_F(SourceRange, IsNotNull) -{ - ::SourceRange sourceRange = diagnostic.ranges()[0]; - - ASSERT_FALSE(sourceRange.isNull()); -} - -TEST_F(SourceRange, Size) -{ - ASSERT_THAT(diagnostic.ranges().size(), 2); -} - -TEST_F(SourceRange, DISABLED_ON_WINDOWS(Start)) -{ - ASSERT_THAT(sourceRange.start(), IsSourceLocation(Utf8StringLiteral("diagnostic_source_range.cpp"), - 8, - 5, - 43)); -} - -TEST_F(SourceRange, DISABLED_ON_WINDOWS(End)) -{ - ASSERT_THAT(sourceRange.end(), IsSourceLocation(Utf8StringLiteral("diagnostic_source_range.cpp"), - 8, - 6, - 44)); -} - -TEST_F(SourceRange, Create) -{ - ASSERT_THAT(sourceRange, ::SourceRange(sourceRange.start(), sourceRange.end())); -} - -TEST_F(SourceRange, SourceRangeFromTranslationUnit) -{ - auto sourceRangeFromTranslationUnit = translationUnit.sourceRange(8u, 5u, 8u, 6u); - - ASSERT_THAT(sourceRangeFromTranslationUnit, sourceRange); -} - -TEST_F(SourceRange, InvalidRangeIsFilteredOut) -{ - ASSERT_THAT(diagnosticWithFilteredOutInvalidRange.ranges(), IsEmpty()); -} - -std::unique_ptr<const Data> SourceRange::data; - -void SourceRange::SetUpTestCase() -{ - data = std::make_unique<const Data>(); -} - -void SourceRange::TearDownTestCase() -{ - data.reset(); -} - -} diff --git a/tests/unit/unittest/token-test.cpp b/tests/unit/unittest/token-test.cpp deleted file mode 100644 index f5f8a36e3a..0000000000 --- a/tests/unit/unittest/token-test.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include "unittest-utility-functions.h" - -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangstring.h> -#include <clangtranslationunit.h> -#include <cursor.h> -#include <sourcelocation.h> -#include <sourcerange.h> -#include <token.h> -#include <unsavedfiles.h> - -using ClangBackEnd::Cursor; -using ClangBackEnd::Document; -using ClangBackEnd::TranslationUnit; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::Documents; -using ClangBackEnd::ClangString; -using ClangBackEnd::SourceLocation; -using ClangBackEnd::SourceRange; -using ClangBackEnd::Token; -using ClangBackEnd::Tokens; - -namespace { - -struct Data { - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/token.cpp")}; - Utf8StringVector compilationArguments{ - UnitTest::addPlatformArguments({Utf8StringLiteral("-std=c++11")})}; - Document document{filePath, compilationArguments, {}, documents}; - TranslationUnit translationUnit{filePath, - filePath, - document.translationUnit().cxIndex(), - document.translationUnit().cxTranslationUnit()}; -}; - -class Token : public ::testing::Test -{ -protected: - static void SetUpTestCase() - { - d = std::make_unique<const Data>(); - d->document.parse(); - } - -protected: - static std::unique_ptr<const Data> d; - const Document &document = d->document; - const TranslationUnit &translationUnit = d->translationUnit; - const SourceRange range{{translationUnit.cxTranslationUnit(), - clang_getLocation(translationUnit.cxTranslationUnit(), - clang_getFile(translationUnit.cxTranslationUnit(), - d->filePath.constData()), - 1, 1)}, - {translationUnit.cxTranslationUnit(), - clang_getLocation(translationUnit.cxTranslationUnit(), - clang_getFile(translationUnit.cxTranslationUnit(), - d->filePath.constData()), - 3, 2)}}; - const Tokens tokens{range}; -}; - -std::unique_ptr<const Data> Token::d; - -TEST_F(Token, CreateTokens) -{ - ASSERT_THAT(tokens.size(), 8u); -} - -TEST_F(Token, AnnotateTokens) -{ - auto cursors = tokens.annotate(); - - ASSERT_THAT(cursors.size(), 8u); -} - -TEST_F(Token, TokenKind) -{ - auto kind = tokens[0].kind(); - - ASSERT_THAT(kind, CXToken_Keyword); -} - -TEST_F(Token, TokenLocation) -{ - auto location = range.start(); - - auto tokenLocation = tokens[0].location(); - - ASSERT_THAT(tokenLocation, location); -} - -TEST_F(Token, TokenSpelling) -{ - auto spelling = tokens[0].spelling(); - - ASSERT_THAT(spelling, "void"); -} - -TEST_F(Token, TokenExtent) -{ - ::SourceRange tokenRange(range.start(), ::SourceLocation(translationUnit.cxTranslationUnit(), - clang_getLocation(translationUnit.cxTranslationUnit(), - clang_getFile(translationUnit.cxTranslationUnit(), - d->filePath.constData()), - 1, 5))); - - auto extent = tokens[0].extent(); - - ASSERT_THAT(extent, tokenRange); -} - - -} diff --git a/tests/unit/unittest/tokenprocessor-test.cpp b/tests/unit/unittest/tokenprocessor-test.cpp deleted file mode 100644 index 0a6106569f..0000000000 --- a/tests/unit/unittest/tokenprocessor-test.cpp +++ /dev/null @@ -1,1871 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" -#include "unittest-utility-functions.h" - -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangtranslationunit.h> -#include <cursor.h> -#include <clangsupport_global.h> -#include <clangstring.h> -#include <fulltokeninfo.h> -#include <sourcelocation.h> -#include <sourcerange.h> -#include <tokeninfo.h> -#include <tokenprocessor.h> -#include <unsavedfiles.h> - -#include <clang-c/Index.h> - -using ClangBackEnd::Cursor; -using ClangBackEnd::HighlightingTypes; -using ClangBackEnd::TokenInfo; -using ClangBackEnd::TokenProcessor; -using ClangBackEnd::HighlightingType; -using ClangBackEnd::Document; -using ClangBackEnd::Documents; -using ClangBackEnd::TranslationUnit; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::ClangString; -using ClangBackEnd::SourceRange; - -using testing::PrintToString; -using testing::IsNull; -using testing::NotNull; -using testing::Gt; -using testing::Contains; -using testing::ElementsAre; -using testing::_; -using testing::EndsWith; -using testing::AllOf; -using testing::Not; -using testing::IsEmpty; -using testing::SizeIs; - -namespace { - -MATCHER_P4(IsHighlightingMark, line, column, length, type, - std::string(negation ? "isn't " : "is ") - + PrintToString(line) + ", " - + PrintToString(column) + ", " - + PrintToString(length) + ", " - + PrintToString(type) + ", " - ) -{ - return arg.line() == line && arg.column() == column && arg.length() == length - && arg.types().mainHighlightingType == type; -} - -MATCHER_P(HasOnlyType, type, - std::string(negation ? "isn't " : "is ") - + PrintToString(type) - ) -{ - return arg.hasOnlyType(type); -} - -MATCHER_P2(HasTwoTypes, firstType, secondType, - std::string(negation ? "isn't " : "is ") - + PrintToString(firstType) - + " and " - + PrintToString(secondType) - ) -{ - return arg.hasMainType(firstType) && arg.hasMixinTypeAt(0, secondType) && arg.mixinSize() == 1; -} - -MATCHER_P3(HasThreeTypes, firstType, secondType, thirdType, - std::string(negation ? "isn't " : "is ") - + PrintToString(firstType) - + ", " - + PrintToString(secondType) - + " and " - + PrintToString(thirdType) - ) -{ - return arg.hasMainType(firstType) && arg.hasMixinTypeAt(0, secondType) && arg.hasMixinTypeAt(1, thirdType) && arg.mixinSize() == 2; -} - -MATCHER_P(HasMixin, mixinType, - std::string(negation ? "isn't " : "is ") - + PrintToString(mixinType) - ) -{ - return arg.hasMixinType(mixinType); -} - -struct Data { - Data() - { - document.parse(); - } - - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{unsavedFiles}; - Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/highlightingmarks.cpp")}; - Document document{filePath, - UnitTest::addPlatformArguments( - {Utf8StringLiteral("-std=c++14"), - Utf8StringLiteral("-I" TESTDATA_DIR)}), - {}, - documents}; - TranslationUnit translationUnit{filePath, - filePath, - document.translationUnit().cxIndex(), - document.translationUnit().cxTranslationUnit()}; -}; - -class TokenProcessor : public ::testing::Test -{ -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - - SourceRange sourceRange(uint line, uint columnEnd) const; - SourceRange sourceRangeMultiLine(uint firstLine, uint lastLine, uint columnEnd) const; - -protected: - static Data *d; - const TranslationUnit &translationUnit = d->translationUnit; -}; - -TEST_F(TokenProcessor, CreateNullInformations) -{ - ::TokenProcessor<TokenInfo> infos; - - ASSERT_TRUE(infos.isNull()); -} - -TEST_F(TokenProcessor, NullInformationsAreEmpty) -{ - ::TokenProcessor<TokenInfo> infos; - - ASSERT_TRUE(infos.isEmpty()); -} - -TEST_F(TokenProcessor, IsNotNull) -{ - const auto aRange = translationUnit.sourceRange(3, 1, 5, 1); - - const auto infos = translationUnit.tokenInfosInRange(aRange); - - ASSERT_FALSE(infos.isNull()); -} - -TEST_F(TokenProcessor, IteratorBeginEnd) -{ - const auto aRange = translationUnit.sourceRange(3, 1, 5, 1); - const auto infos = translationUnit.tokenInfosInRange(aRange); - - const auto endIterator = std::next(infos.begin(), infos.size()); - - ASSERT_THAT(infos.end(), endIterator); -} - -TEST_F(TokenProcessor, ForFullTranslationUnitRange) -{ - const auto infos = translationUnit.tokenInfos(); - - ASSERT_THAT(infos, AllOf(Contains(IsHighlightingMark(1u, 1u, 4u, HighlightingType::Keyword)), - Contains(IsHighlightingMark(277u, 5u, 15u, HighlightingType::Function)))); -} - -TEST_F(TokenProcessor, Size) -{ - const auto range = translationUnit.sourceRange(5, 5, 5, 10); - - const auto infos = translationUnit.tokenInfosInRange(range); - - ASSERT_THAT(infos.size(), 1); -} - -TEST_F(TokenProcessor, DISABLED_Keyword) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(5, 12)); - - ASSERT_THAT(infos[0], IsHighlightingMark(5u, 5u, 6u, HighlightingType::Keyword)); -} - -TEST_F(TokenProcessor, StringLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(1, 29)); - - ASSERT_THAT(infos[4], IsHighlightingMark(1u, 24u, 10u, HighlightingType::StringLiteral)); -} - -TEST_F(TokenProcessor, Utf8StringLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(2, 33)); - - ASSERT_THAT(infos[4], IsHighlightingMark(2u, 24u, 12u, HighlightingType::StringLiteral)); -} - -TEST_F(TokenProcessor, RawStringLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(3, 34)); - - ASSERT_THAT(infos[4], IsHighlightingMark(3u, 24u, 13u, HighlightingType::StringLiteral)); -} - -TEST_F(TokenProcessor, CharacterLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(4, 28)); - - ASSERT_THAT(infos[3], IsHighlightingMark(4u, 24u, 3u, HighlightingType::StringLiteral)); -} - -TEST_F(TokenProcessor, IntegerLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(23, 26)); - - ASSERT_THAT(infos[3], IsHighlightingMark(23u, 24u, 1u, HighlightingType::NumberLiteral)); -} - -TEST_F(TokenProcessor, FloatLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(24, 29)); - - ASSERT_THAT(infos[3], IsHighlightingMark(24u, 24u, 4u, HighlightingType::NumberLiteral)); -} - -TEST_F(TokenProcessor, FunctionDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(45, 20)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Function, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); -} - -TEST_F(TokenProcessor, MemberFunctionDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(52, 29)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Function, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); -} - -TEST_F(TokenProcessor, VirtualMemberFunctionDefinitionOutsideOfClassBody) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(586, 37)); - - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::VirtualFunction, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); -} - -TEST_F(TokenProcessor, VirtualMemberFunctionDefinitionInsideOfClassBody) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(589, 47)); - - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::VirtualFunction, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); -} - -TEST_F(TokenProcessor, FunctionDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(55, 32)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); -} - -TEST_F(TokenProcessor, MemberFunctionDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(59, 27)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); -} - -TEST_F(TokenProcessor, MemberFunctionReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(104, 35)); - - ASSERT_THAT(infos[0], IsHighlightingMark(104u, 9u, 23u, HighlightingType::Function)); -} - -TEST_F(TokenProcessor, FunctionCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(64, 16)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, TypeConversionFunction) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(68, 20)); - - ASSERT_THAT(infos[1], IsHighlightingMark(68u, 14u, 3u, HighlightingType::Type)); -} - -TEST_F(TokenProcessor, InbuiltTypeConversionFunction) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(69, 20)); - - ASSERT_THAT(infos[1], IsHighlightingMark(69u, 14u, 3u, HighlightingType::PrimitiveType)); -} - -TEST_F(TokenProcessor, TypeReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(74, 13)); - - ASSERT_THAT(infos[0], IsHighlightingMark(74u, 5u, 3u, HighlightingType::Type)); -} - -TEST_F(TokenProcessor, LocalVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(79, 13)); - - ASSERT_THAT(infos[1], IsHighlightingMark(79u, 9u, 3u, HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, LocalVariableDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(79, 13)); - - ASSERT_THAT(infos[1], IsHighlightingMark(79u, 9u, 3u, HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, LocalVariableReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(81, 26)); - - ASSERT_THAT(infos[0], IsHighlightingMark(81u, 5u, 3u, HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, ParameterFunctionArgumentDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(84, 45)); - - ASSERT_THAT(infos[5], IsHighlightingMark(84u, 41u, 3u, HighlightingType::Parameter)); -} - -TEST_F(TokenProcessor, ParameterFunctionArgumentReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(86, 26)); - - ASSERT_THAT(infos[0], IsHighlightingMark(86u, 5u, 3u, HighlightingType::Parameter)); -} - -TEST_F(TokenProcessor, ClassVariableDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(90, 21)); - - ASSERT_THAT(infos[1], IsHighlightingMark(90u, 9u, 11u, HighlightingType::Field)); -} - -TEST_F(TokenProcessor, ClassVariableReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(94, 23)); - - ASSERT_THAT(infos[0], IsHighlightingMark(94u, 9u, 11u, HighlightingType::Field)); -} - -TEST_F(TokenProcessor, StaticMethodDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(110, 25)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); -} - -TEST_F(TokenProcessor, StaticMethodReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(114, 30)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, Enumeration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(118, 17)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Enum)); -} - -TEST_F(TokenProcessor, Enumerator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(120, 15)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Enumeration)); -} - -TEST_F(TokenProcessor, EnumerationReferenceDeclarationType) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(125, 28)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Enum)); -} - -TEST_F(TokenProcessor, EnumerationReferenceDeclarationVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(125, 28)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, EnumerationReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(127, 30)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, EnumeratorReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(127, 30)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Enumeration)); -} - -TEST_F(TokenProcessor, ClassForwardDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(130, 12)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, ConstructorDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(134, 13)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); -} - -TEST_F(TokenProcessor, DestructorDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(135, 15)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); -} - -TEST_F(TokenProcessor, ClassForwardDeclarationReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(138, 23)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, ClassTypeReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(140, 32)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, ConstructorReferenceVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(140, 32)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, UnionDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(145, 12)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Union)); -} - -TEST_F(TokenProcessor, UnionDeclarationReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(150, 33)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Union)); -} - -TEST_F(TokenProcessor, GlobalVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(150, 33)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::GlobalVariable)); -} - -TEST_F(TokenProcessor, StructDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(50, 11)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Struct)); -} - -TEST_F(TokenProcessor, NameSpace) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(160, 22)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Namespace)); -} - -TEST_F(TokenProcessor, NameSpaceAlias) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(164, 38)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Type, HighlightingType::Namespace)); -} - -TEST_F(TokenProcessor, UsingStructInNameSpace) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(165, 36)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenProcessor, NameSpaceReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(166, 35)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Namespace)); -} - -TEST_F(TokenProcessor, StructInNameSpaceReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(166, 35)); - - ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Struct)); -} - -TEST_F(TokenProcessor, VirtualFunctionDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(170, 35)); - - ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::VirtualFunction, HighlightingType::Declaration)); -} - -TEST_F(TokenProcessor, DISABLED_NonVirtualFunctionCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(177, 46)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, DISABLED_NonVirtualFunctionCallPointer) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(180, 54)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, VirtualFunctionCallPointer) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(192, 51)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::VirtualFunction)); -} - -TEST_F(TokenProcessor, FinalVirtualFunctionCallPointer) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(202, 61)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, NonFinalVirtualFunctionCallPointer) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(207, 61)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::VirtualFunction)); -} - -TEST_F(TokenProcessor, OverriddenPlusOperatorDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(220, 67)); - - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); -} - -TEST_F(TokenProcessor, CallToOverriddenPlusOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(224, 49)); - - ASSERT_THAT(infos[6], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); -} - -TEST_F(TokenProcessor, CallToOverriddenPlusAssignOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(226, 24)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); -} - -TEST_F(TokenProcessor, OverriddenStarOperatorMemberDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(604, 26)); - - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); -} - -TEST_F(TokenProcessor, OverriddenStarOperatorNonMemberDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); - - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); -} - -TEST_F(TokenProcessor, IntegerCallToOverriddenBinaryOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(613, 9)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); -} - -TEST_F(TokenProcessor, FloatCallToOverriddenBinaryOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(614, 9)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); -} - -TEST_F(TokenProcessor, LeftShiftAssignmentOperatorMemberDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(618, 32)); - - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Punctuation)); // ( is a punctuation. -} - -TEST_F(TokenProcessor, CalledLeftShiftAssignmentOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(629, 18)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::NumberLiteral)); -} - -TEST_F(TokenProcessor, FunctionCallOperatorMemberDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(619, 29)); - - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Punctuation)); // ( is a punctuation. -} - -TEST_F(TokenProcessor, CalledFunctionCallOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(632, 16)); - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); -} - -TEST_F(TokenProcessor, AccessOperatorMemberDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(620, 38)); - - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); - ASSERT_THAT(infos[4], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Punctuation)); // ( is a punctuation. -} - -TEST_F(TokenProcessor, CalledAccessOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(633, 16)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); -} - -TEST_F(TokenProcessor, NewOperatorMemberDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(621, 39)); - - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Keyword, HighlightingType::Operator, HighlightingType::OverloadedOperator)); - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Punctuation)); // ( is a punctuation. -} - -TEST_F(TokenProcessor, CalledNewOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(635, 34)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Punctuation)); // = is not marked. - // CLANG-UPGRADE-CHECK: Check if 'new' keyword usage cursor correctly returns referenced() cursor - // and uncomment this test in that case. - // ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // new -} - -TEST_F(TokenProcessor, DeleteOperatorMemberDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(622, 37)); - - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Keyword, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // delete - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Punctuation)); // ( is a punctuation. -} - -TEST_F(TokenProcessor, CalledDeleteOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(636, 20)); - - // CLANG-UPGRADE-CHECK: Check if 'delete' keyword usage cursor correctly returns referenced() cursor - // and uncomment this test in that case. - // ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // delete - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Punctuation)); // ; is a punctuation. -} - -TEST_F(TokenProcessor, NewArrayOperatorMemberDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(623, 41)); - - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Keyword, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // new - ASSERT_THAT(infos[4], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // [ - ASSERT_THAT(infos[5], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // ] - ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::Punctuation)); // ( is a punctuation. -} - -TEST_F(TokenProcessor, CalledNewArrayOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(637, 34)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Punctuation)); // = is not marked. - // CLANG-UPGRADE-CHECK: Check if 'new' keyword usage cursor correctly returns referenced() cursor - // and uncomment this test in that case. - // ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // new -} - -TEST_F(TokenProcessor, DeleteArrayOperatorMemberDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(624, 39)); - - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Keyword, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // delete - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // [ - ASSERT_THAT(infos[4], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // ] - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Punctuation)); // ( is a punctuation. -} - -TEST_F(TokenProcessor, CalledDeleteArrayOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(638, 20)); - - // CLANG-UPGRADE-CHECK: Check if 'delete' keyword usage cursor correctly returns referenced() cursor - // and uncomment this test in that case. - // ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // delete -} - -TEST_F(TokenProcessor, CalledNotOverloadedOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(634, 22)); - - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Keyword)); // new -} - -TEST_F(TokenProcessor, ParenthesisOperatorWithoutArguments) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(654, 25)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Keyword, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // operator - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '(' - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // ')' - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Punctuation)); // second '(' is a punctuation -} - -TEST_F(TokenProcessor, CalledParenthesisOperatorWithoutArguments) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(662, 14)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '(' - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // ')' -} - -TEST_F(TokenProcessor, OperatorWithOnePunctuationTokenWithoutArguments) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(655, 25)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Keyword, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // operator - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '*' - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Punctuation)); // ( is a punctuation -} - -TEST_F(TokenProcessor, CalledOperatorWithOnePunctuationTokenWithoutArguments) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(663, 13)); - - ASSERT_THAT(infos[0], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '*' -} - -TEST_F(TokenProcessor, EqualsOperatorOverload) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(656, 43)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Keyword, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // operator - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '=' - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Punctuation)); // ( is a punctuation -} - -TEST_F(TokenProcessor, CalledEqualsOperatorOverload) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(664, 23)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '=' -} - -TEST_F(TokenProcessor, LeftParenthesisIsAPunctuation) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, SeparatingCommaIsAPunctuation) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); - - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, RightParenthesisIsAPunctuation) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); - - ASSERT_THAT(infos[7], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, CurlyLeftParenthesisIsAPunctuation) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); - - ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, CurlyRightParenthesisIsAPunctuation) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); - - ASSERT_THAT(infos[9], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, OperatorColon) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(668, 28)); - - ASSERT_THAT(infos[6], HasThreeTypes(HighlightingType::Punctuation, HighlightingType::Operator, - HighlightingType::TernaryElse)); -} - -TEST_F(TokenProcessor, PunctuationColon) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(133, 10)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, LessThanOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(668, 28)); - - ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Punctuation, HighlightingType::Operator)); -} - -TEST_F(TokenProcessor, LessThanPunctuation) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(247, 10)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Punctuation, - HighlightingType::AngleBracketOpen)); -} - -TEST_F(TokenProcessor, GreaterThanPunctuation) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(247, 19)); - - ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Punctuation, - HighlightingType::AngleBracketClose)); -} - -TEST_F(TokenProcessor, Comment) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(229, 14)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Comment)); -} - -TEST_F(TokenProcessor, PreprocessingDirective) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(231, 37)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Preprocessor)); -} - -TEST_F(TokenProcessor, PreprocessorMacroDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(231, 37)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::PreprocessorDefinition)); -} - -TEST_F(TokenProcessor, PreprocessorFunctionMacroDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(232, 47)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::PreprocessorDefinition)); -} - -TEST_F(TokenProcessor, PreprocessorMacroExpansion) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(236, 27)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); -} - -TEST_F(TokenProcessor, PreprocessorMacroExpansionArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(236, 27)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::NumberLiteral)); -} - -TEST_F(TokenProcessor, PreprocessorInclusionDirective) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(239, 18)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Preprocessor)); - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::StringLiteral)); -} - -TEST_F(TokenProcessor, GotoLabelStatement) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(242, 12)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Label)); -} - -TEST_F(TokenProcessor, GotoLabelStatementReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(244, 21)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Label)); -} - -TEST_F(TokenProcessor, TemplateReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(254, 25)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, TemplateTypeParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[3], HasTwoTypes(HighlightingType::Type, - HighlightingType::TemplateTypeParameter)); -} - -TEST_F(TokenProcessor, TemplateDefaultParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[5], HasTwoTypes(HighlightingType::Type, HighlightingType::Struct)); -} - -TEST_F(TokenProcessor, NonTypeTemplateParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, NonTypeTemplateParameterDefaultArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::NumberLiteral)); -} - -TEST_F(TokenProcessor, TemplateTemplateParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[17], HasTwoTypes(HighlightingType::Type, - HighlightingType::TemplateTemplateParameter)); -} - -TEST_F(TokenProcessor, TemplateTemplateParameterDefaultArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[19], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, TemplateFunctionDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(266, 63)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Function, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); -} - -TEST_F(TokenProcessor, TemplateTypeParameterReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(268, 58)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, - HighlightingType::TemplateTypeParameter)); -} - -TEST_F(TokenProcessor, TemplateTypeParameterDeclarationReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(268, 58)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, NonTypeTemplateParameterReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(269, 71)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, NonTypeTemplateParameterReferenceReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(269, 71)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, TemplateTemplateParameterReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(270, 89)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, - HighlightingType::TemplateTemplateParameter)); -} - -TEST_F(TokenProcessor, TemplateTemplateContainerParameterReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(270, 89)); - - ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, - HighlightingType::TemplateTypeParameter)); -} - -TEST_F(TokenProcessor, TemplateTemplateParameterReferenceVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(270, 89)); - - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, ClassFinalVirtualFunctionCallPointer) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(212, 61)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, ClassFinalVirtualFunctionCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(277, 23)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, HasFunctionArguments) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(286, 29)); - - ASSERT_TRUE(infos[1].hasFunctionArguments()); -} - -TEST_F(TokenProcessor, PreprocessorInclusionDirectiveWithAngleBrackets ) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(289, 38)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Preprocessor)); - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::StringLiteral)); -} - -TEST_F(TokenProcessor, ArgumentInMacroExpansionIsKeyword) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(302, 36)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::PrimitiveType)); -} - -TEST_F(TokenProcessor, DISABLED_FirstArgumentInMacroExpansionIsLocalVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(302, 36)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenProcessor, DISABLED_SecondArgumentInMacroExpansionIsLocalVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(302, 36)); - - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenProcessor, DISABLED_SecondArgumentInMacroExpansionIsField) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(310, 40)); - - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); -} - - -TEST_F(TokenProcessor, EnumerationType) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(316, 30)); - - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Enum)); -} - -TEST_F(TokenProcessor, TypeInStaticCast) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(328, 64)); - - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenProcessor, StaticCastIsKeyword) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(328, 64)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Keyword)); -} - -TEST_F(TokenProcessor, StaticCastPunctation) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(328, 64)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Punctuation, - HighlightingType::AngleBracketOpen)); - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Punctuation)); - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, TypeInReinterpretCast) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(329, 69)); - - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenProcessor, IntegerAliasDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(333, 41)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias)); -} - -TEST_F(TokenProcessor, IntegerAlias) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(341, 31)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias)); -} - -TEST_F(TokenProcessor, SecondIntegerAlias) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(342, 43)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias)); -} - -TEST_F(TokenProcessor, IntegerTypedef) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(343, 35)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Typedef)); -} - -TEST_F(TokenProcessor, FunctionAlias) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(344, 16)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias)); -} - -TEST_F(TokenProcessor, FriendTypeDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(350, 28)); - - ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, FriendArgumentTypeDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(351, 65)); - - ASSERT_THAT(infos[6], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, FriendArgumentDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(351, 65)); - - ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::Parameter)); -} - -TEST_F(TokenProcessor, FieldInitialization) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(358, 18)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Field)); -} - -TEST_F(TokenProcessor, TemplateFunctionCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(372, 29)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, TemplatedType) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(377, 21)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, TemplatedTypeDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(384, 49)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, NoOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(389, 24)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, ScopeOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(400, 33)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, TemplateClassNamespace) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Namespace)); -} - -TEST_F(TokenProcessor, TemplateClass) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); - - ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, TemplateClassParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); - - ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, TemplateClassDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); - - ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, TypeDefDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(418, 36)); - - ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Typedef)); -} - -TEST_F(TokenProcessor, TypeDefDeclarationUsage) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(419, 48)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Typedef)); -} - -TEST_F(TokenProcessor, NonConstReferenceArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(455, 35)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, ConstReferenceArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(464, 32)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, RValueReferenceArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(473, 52)); - - infos[1]; - - ASSERT_THAT(infos[8], - HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, NonConstPointerArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(482, 33)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, PointerToConstArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(490, 31)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, ConstPointerArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(491, 30)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, NonConstPointerGetterAsArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(580, 42)); - - infos[1]; - - ASSERT_THAT(infos[2] ,HasMixin(HighlightingType::OutputArgument)); - ASSERT_THAT(infos[3], HasMixin(HighlightingType::OutputArgument)); - ASSERT_THAT(infos[4], HasMixin(HighlightingType::OutputArgument)); - ASSERT_THAT(infos[5], HasMixin(HighlightingType::OutputArgument)); - ASSERT_THAT(infos[6], HasMixin(HighlightingType::OutputArgument)); - ASSERT_THAT(infos[7], Not(HasMixin(HighlightingType::OutputArgument))); -} - -TEST_F(TokenProcessor, NonConstReferenceArgumentCallInsideCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(501, 64)); - infos[1]; - - infos[3]; - - ASSERT_THAT(infos[7], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, OutputArgumentsAreEmptyAfterIteration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(501, 63)); - - for (const auto &info : infos ) { Q_UNUSED(info) } - - ASSERT_TRUE(infos.currentOutputArgumentRangesAreEmpty()); -} - -TEST_F(TokenProcessor, NonConstReferenceArgumentFromFunctionParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(506, 42)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasTwoTypes(HighlightingType::Parameter, HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, NonConstPointerArgumentAsExpression) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(513, 33)); - - infos[1]; - - ASSERT_THAT(infos[3], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, NonConstPointerArgumentAsInstanceWithMember) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(525, 46)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, NonConstPointerArgumentAsMemberOfInstance) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(525, 46)); - - infos[1]; - infos[2]; - - ASSERT_THAT(infos[4], - HasTwoTypes(HighlightingType::Field, HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, DISABLED_NonConstReferenceArgumentConstructor) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(540, 57)); - - infos[2]; - - ASSERT_THAT(infos[3], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, DISABLED_NonConstReferenceMemberInitialization) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(546, 19)); - - infos[2]; - - ASSERT_THAT(infos[3], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, EnumerationTypeDef) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(424, 41)); - - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Enum)); -} - -// QTCREATORBUG-15473 -TEST_F(TokenProcessor, DISABLED_ArgumentToUserDefinedIndexOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(434, 19)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, ClassTemplateParticalSpecialization) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(553, 33)); - - ASSERT_THAT(infos[6], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Class)); -} - -TEST_F(TokenProcessor, UsingFunction) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(556, 27)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, PreprocessorIfDirective) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(558, 6)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Preprocessor)); -} - -TEST_F(TokenProcessor, PreprocessorInclusionDirectiveWithKeyword) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(561, 15)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::StringLiteral)); -} - -TEST_F(TokenProcessor, VariableInOperatorFunctionCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(566, 12)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Parameter)); -} - -TEST_F(TokenProcessor, UsingTemplateFunction) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(584, 17)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, HeaderNameIsInclusion) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(239, 31)); - - ClangBackEnd::TokenInfoContainer container(infos[2]); - - ASSERT_THAT(container.extraInfo.includeDirectivePath, true); -} - -TEST_F(TokenProcessor, HeaderNameIsInclusionWithAngleBrackets) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(289, 31)); - - ClangBackEnd::TokenInfoContainer container(infos[2]); - - ASSERT_THAT(container.extraInfo.includeDirectivePath, true); -} - -TEST_F(TokenProcessor, NotInclusion) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(241, 13)); - - ClangBackEnd::TokenInfoContainer container(infos[1]); - - ASSERT_THAT(container.extraInfo.includeDirectivePath, false); -} - -TEST_F(TokenProcessor, MacroIsIdentifier) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(232, 30)); - - ClangBackEnd::TokenInfoContainer container(infos[2]); - - ASSERT_THAT(container.extraInfo.identifier, true); -} - -TEST_F(TokenProcessor, DefineIsNotIdentifier) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(232, 30)); - - ClangBackEnd::TokenInfoContainer container(infos[1]); - - ASSERT_THAT(container.extraInfo.includeDirectivePath, false); -} - -TEST_F(TokenProcessor, NamespaceTypeSpelling) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(592, 59)); - ClangBackEnd::TokenInfoContainer container(infos[10]); - ASSERT_THAT(container.extraInfo.semanticParentTypeSpelling, Utf8StringLiteral("NFoo::NBar::NTest")); -} - -TEST_F(TokenProcessor, TypeNameOfInvalidDeclarationIsInvalid) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(594, 14)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenProcessor, VariableNameOfInvalidDeclarationIsInvalid) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(594, 14)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenProcessor, QtPropertyName) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(599, 103)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); - ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::QtProperty)); -} - -TEST_F(TokenProcessor, QtPropertyNameMultiLine) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRangeMultiLine(704, 732, 14)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); - ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::QtProperty)); -} - -TEST_F(TokenProcessor, QtPropertyFunction) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(599, 103)); - - ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, QtPropertyFunctionMultiLine) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRangeMultiLine(704, 732, 14)); - - ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, QtPropertyInternalKeyword) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(599, 103)); - - ASSERT_THAT(infos[9], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenProcessor, QtPropertyInternalKeywordMultiLine) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRangeMultiLine(704, 732, 14)); - - ASSERT_THAT(infos[9], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenProcessor, QtPropertyLastToken) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(599, 103)); - - ASSERT_THAT(infos[14], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, QtPropertyLastTokenMultiLine) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRangeMultiLine(704, 732, 14)); - - ASSERT_THAT(infos[14], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenProcessor, QtPropertyType) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(600, 46)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenProcessor, CursorRange) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(592, 15)); - const auto expectedRange = translationUnit.sourceRange(592, 1, 592, 87); - - ClangBackEnd::TokenInfoContainer container(infos[1]); - - ASSERT_THAT(container.extraInfo.cursorRange, expectedRange); -} - -TEST_F(TokenProcessor, AnonymousEnum) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(641, 7)); - - ClangBackEnd::TokenInfoContainer container(infos[0]); - - ASSERT_THAT(container.types.mainHighlightingType, ClangBackEnd::HighlightingType::Keyword); - ASSERT_THAT(container.types.mixinHighlightingTypes[0], ClangBackEnd::HighlightingType::Enum); -} - -TEST_F(TokenProcessor, AnonymousNamespace) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(645, 12)); - - ClangBackEnd::TokenInfoContainer container(infos[0]); - - ASSERT_THAT(container.types.mainHighlightingType, ClangBackEnd::HighlightingType::Keyword); - ASSERT_THAT(container.types.mixinHighlightingTypes[0], ClangBackEnd::HighlightingType::Namespace); -} - -TEST_F(TokenProcessor, AnonymousStruct) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(647, 13)); - - ClangBackEnd::TokenInfoContainer container(infos[0]); - - ASSERT_THAT(container.types.mainHighlightingType, ClangBackEnd::HighlightingType::Keyword); - ASSERT_THAT(container.types.mixinHighlightingTypes[0], ClangBackEnd::HighlightingType::Struct); -} - -TEST_F(TokenProcessor, LexicalParentIndex) -{ - const auto containers = translationUnit.fullTokenInfosInRange( - translationUnit.sourceRange(50, 1, 53, 3)).toTokenInfoContainers(); - - ASSERT_THAT(containers[4].extraInfo.lexicalParentIndex, 1); -} - -TEST_F(TokenProcessor, QtOldStyleSignal) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(672, 32)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenProcessor, QtOldStyleSlot) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(673, 30)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenProcessor, QtOldStyleSignalFunctionPointerType) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(674, 50)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); - ASSERT_THAT(infos[7], HasOnlyType(HighlightingType::Type)); - ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenProcessor, NonConstParameterConstructor) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(681, 90)); - - infos[1]; - - ASSERT_THAT(infos[4], Not(HasMixin(HighlightingType::OutputArgument))); -} - -TEST_F(TokenProcessor, DISABLED_NonConstArgumentConstructor) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(686, 47)); - - infos[2]; - - ASSERT_THAT(infos[3], HasMixin(HighlightingType::OutputArgument)); -} - -TEST_F(TokenProcessor, LambdaLocalVariableCapture) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(442, 47)); - - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, StaticProtectedMember) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(693, 31)); - - ClangBackEnd::TokenInfoContainer container(infos[2]); - - ASSERT_THAT(container.extraInfo.accessSpecifier, ClangBackEnd::AccessSpecifier::Protected); -} - -TEST_F(TokenProcessor, StaticPrivateMember) -{ - const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(696, 29)); - - ClangBackEnd::TokenInfoContainer container(infos[2]); - - ASSERT_THAT(container.extraInfo.accessSpecifier, ClangBackEnd::AccessSpecifier::Private); -} - -TEST_F(TokenProcessor, TemplateAlias) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(701, 8)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias)); -} - -TEST_F(TokenProcessor, StructuredBinding) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(737, 23)); - - ASSERT_THAT(infos[3], IsHighlightingMark(737u, 17u, 1u, HighlightingType::LocalVariable)); - ASSERT_THAT(infos[5], IsHighlightingMark(737u, 20u, 1u, HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, IndirectMacro) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(746, 32)); - - ASSERT_THAT(infos[5], IsHighlightingMark(746u, 20u, 10u, HighlightingType::LocalVariable)); -} - -TEST_F(TokenProcessor, MultiDimArray) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(752, 28)); - - ASSERT_THAT(infos[3], IsHighlightingMark(752u, 13u, 10u, HighlightingType::GlobalVariable)); -} - -TEST_F(TokenProcessor, TemplateSeparateDeclDef) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRangeMultiLine(755, 771, 1)); - ASSERT_THAT(infos[11], IsHighlightingMark(757u, 17u, 10u, HighlightingType::Invalid)); - ASSERT_THAT(infos[37], IsHighlightingMark(764u, 5u, 9u, HighlightingType::GlobalVariable)); -} - -TEST_F(TokenProcessor, NestedTemplateIncorrect) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(773, 44)); - ASSERT_THAT(infos[12], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, OperatorInTemplate) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(787, 28)); - ASSERT_THAT(infos[9], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, CyrillicString) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(792, 28)); - ASSERT_THAT(infos[5], IsHighlightingMark(792u, 24u, 3u, HighlightingType::StringLiteral)); -} - -TEST_F(TokenProcessor, PreProcessorInStruct) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(795, 14)); - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Preprocessor)); -} - -TEST_F(TokenProcessor, DefinitionWithComparison) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(798, 39)); - ASSERT_THAT(infos[13], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, GlobalVariableWithComparison) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(800, 18)); - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Punctuation)); -} - -TEST_F(TokenProcessor, VariableWithComparison) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(803, 22)); - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Punctuation)); -} - - -TEST_F(TokenProcessor, NestedTemplate) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(811, 44)); - ASSERT_THAT(infos[12], HasTwoTypes(HighlightingType::Punctuation, - HighlightingType::DoubleAngleBracketClose)); -} - -Data *TokenProcessor::d; - -void TokenProcessor::SetUpTestCase() -{ - d = new Data; -} - -void TokenProcessor::TearDownTestCase() -{ - delete d; - d = nullptr; -} - -ClangBackEnd::SourceRange TokenProcessor::sourceRange(uint line, uint columnEnd) const -{ - return translationUnit.sourceRange(line, 1, line, columnEnd); -} - -ClangBackEnd::SourceRange TokenProcessor::sourceRangeMultiLine(uint firstLine, uint lastLine, - uint columnEnd) const -{ - return translationUnit.sourceRange(firstLine, 1, lastLine, columnEnd); -} - -} diff --git a/tests/unit/unittest/translationunitupdater-test.cpp b/tests/unit/unittest/translationunitupdater-test.cpp deleted file mode 100644 index ea71070351..0000000000 --- a/tests/unit/unittest/translationunitupdater-test.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <clangclock.h> -#include <clangtranslationunitupdater.h> - -#include <clang-c/Index.h> - -using ClangBackEnd::Clock; -using ClangBackEnd::TimePoint; -using ClangBackEnd::TranslationUnitUpdater; -using ClangBackEnd::TranslationUnitUpdateInput; -using ClangBackEnd::TranslationUnitUpdateResult; - -using testing::Eq; -using testing::Gt; - -namespace { - -class TranslationUnitUpdater : public ::testing::Test -{ -protected: - void TearDown() override; - - ::TranslationUnitUpdater createUpdater(const TranslationUnitUpdateInput &input, - const Utf8String &translationUnitId = Utf8String()); - - enum ReparseMode { SetReparseNeeded, DoNotSetReparseNeeded }; - TranslationUnitUpdateInput createInput(ReparseMode reparseMode = DoNotSetReparseNeeded); - -protected: - CXIndex cxIndex = nullptr; - CXTranslationUnit cxTranslationUnit = nullptr; - - Utf8String filePath = Utf8StringLiteral(TESTDATA_DIR"/translationunits.cpp"); -}; - -using TranslationUnitUpdaterSlowTest = TranslationUnitUpdater; - -TEST_F(TranslationUnitUpdaterSlowTest, ParsesIfNeeded) -{ - ::TranslationUnitUpdater updater = createUpdater(createInput()); - - TranslationUnitUpdateResult result = updater.update(::TranslationUnitUpdater::UpdateMode::AsNeeded); - - ASSERT_TRUE(cxTranslationUnit); - ASSERT_FALSE(result.hasReparsed()); -} - -TEST_F(TranslationUnitUpdaterSlowTest, ReparsesIfNeeded) -{ - ::TranslationUnitUpdater updater = createUpdater(createInput(SetReparseNeeded)); - - TranslationUnitUpdateResult result = updater.update(::TranslationUnitUpdater::UpdateMode::AsNeeded); - - ASSERT_TRUE(result.hasReparsed()); -} - -TEST_F(TranslationUnitUpdaterSlowTest, PropagatesTranslationUnitId) -{ - const Utf8String translationUnitId = Utf8StringLiteral("myId"); - ::TranslationUnitUpdater updater = createUpdater(createInput(SetReparseNeeded), translationUnitId); - - TranslationUnitUpdateResult result = updater.update(::TranslationUnitUpdater::UpdateMode::AsNeeded); - - ASSERT_THAT(result.translationUnitId, Eq(translationUnitId)); -} - -TEST_F(TranslationUnitUpdaterSlowTest, UpdatesParseTimePoint) -{ - ::TranslationUnitUpdater updater = createUpdater(createInput()); - const TimePoint now = Clock::now(); - - TranslationUnitUpdateResult result = updater.update(::TranslationUnitUpdater::UpdateMode::AsNeeded); - - ASSERT_TRUE(result.hasParsed()); - ASSERT_THAT(result.parseTimePoint, Gt(now)); -} - -TEST_F(TranslationUnitUpdaterSlowTest, NotUpdatingParseTimePointForReparseOnly) -{ - ::TranslationUnitUpdater updater = createUpdater(createInput()); - TranslationUnitUpdateResult result = updater.update(::TranslationUnitUpdater::UpdateMode::AsNeeded); - - ::TranslationUnitUpdater reparseUpdater = createUpdater(createInput(SetReparseNeeded)); - result = reparseUpdater.update(::TranslationUnitUpdater::UpdateMode::AsNeeded); - - ASSERT_TRUE(result.hasReparsed()); - ASSERT_FALSE(result.hasParsed()); -} - -TEST_F(TranslationUnitUpdaterSlowTest, UpdatesDependentOnFilesOnParse) -{ - ::TranslationUnitUpdater updater = createUpdater(createInput()); - - TranslationUnitUpdateResult result = updater.update(::TranslationUnitUpdater::UpdateMode::AsNeeded); - - ASSERT_FALSE(result.dependedOnFilePaths.isEmpty()); -} - -void TranslationUnitUpdater::TearDown() -{ - clang_disposeTranslationUnit(cxTranslationUnit); - clang_disposeIndex(cxIndex); -} - -::TranslationUnitUpdater -TranslationUnitUpdater::createUpdater(const TranslationUnitUpdateInput &input, - const Utf8String &translationUnitId) -{ - return ::TranslationUnitUpdater(translationUnitId, cxIndex, cxTranslationUnit, input); -} - -TranslationUnitUpdateInput -TranslationUnitUpdater::createInput(ReparseMode reparseMode) -{ - TranslationUnitUpdateInput updateInput; - updateInput.filePath = filePath; - updateInput.reparseNeeded = reparseMode == SetReparseNeeded; - - return updateInput; -} - -} // anonymous diff --git a/tests/unit/unittest/unittest.qbs b/tests/unit/unittest/unittest.qbs index d45103fdba..8fed770aba 100644 --- a/tests/unit/unittest/unittest.qbs +++ b/tests/unit/unittest/unittest.qbs @@ -163,7 +163,6 @@ Project { "processevents-utilities.cpp", "processevents-utilities.h", "readandwritemessageblock-test.cpp", - "rundocumentparse-utility.h", "sizedarray-test.cpp", "smallstring-test.cpp", "sourcerangecontainer-matcher.h", @@ -196,49 +195,9 @@ Project { "activationsequenceprocessor-test.cpp", "chunksreportedmonitor.cpp", "chunksreportedmonitor.h", - "clangasyncjob-base.cpp", - "clangasyncjob-base.h", - "clangcodecompleteresults-test.cpp", - "clangcodemodelserver-test.cpp", "clangcompareoperators.h", - "clangcompletecodejob-test.cpp", - "clangdocument-test.cpp", - "clangdocumentprocessor-test.cpp", - "clangdocumentprocessors-test.cpp", - "clangdocuments-test.cpp", - "clangfollowsymbol-test.cpp", - "clangjobqueue-test.cpp", - "clangjobs-test.cpp", - "clangparsesupportivetranslationunitjob-test.cpp", - "clangrequestannotationsjob-test.cpp", - "clangrequestreferencesjob-test.cpp", - "clangresumedocumentjob-test.cpp", - "clangstring-test.cpp", - "clangsupportivetranslationunitinitializer-test.cpp", - "clangsuspenddocumentjob-test.cpp", - "clangtooltipinfo-test.cpp", - "clangtranslationunit-test.cpp", - "clangtranslationunits-test.cpp", - "clangupdateannotationsjob-test.cpp", - "codecompleter-test.cpp", - "codecompletionsextractor-test.cpp", - "cursor-test.cpp", - "diagnostic-test.cpp", "diagnosticcontainer-matcher.h", - "diagnosticset-test.cpp", - "fixit-test.cpp", - "gtest-clang-printing.cpp", - "gtest-clang-printing.h", "readexporteddiagnostics-test.cpp", - "skippedsourceranges-test.cpp", - "sourcelocation-test.cpp", - "sourcerange-test.cpp", - "token-test.cpp", - "tokenprocessor-test.cpp", - "translationunitupdater-test.cpp", - "unsavedfile-test.cpp", - "unsavedfiles-test.cpp", - "utf8positionfromlinecolumn-test.cpp", ] } @@ -258,124 +217,6 @@ Project { } Group { - name: "sources from clangbackend" - condition: libclang.present - prefix: "../../../src/tools/clangbackend/source/" - files: [ - "clangasyncjob.h", - "clangbackend_global.h", - "clangclock.h", - "clangcodecompleteresults.cpp", - "clangcodecompleteresults.h", - "clangcodemodelserver.cpp", - "clangcodemodelserver.h", - "clangcompletecodejob.cpp", - "clangcompletecodejob.h", - "clangdocument.cpp", - "clangdocument.h", - "clangdocumentjob.h", - "clangdocumentprocessor.cpp", - "clangdocumentprocessor.h", - "clangdocumentprocessors.cpp", - "clangdocumentprocessors.h", - "clangdocuments.cpp", - "clangdocuments.h", - "clangdocumentsuspenderresumer.cpp", - "clangdocumentsuspenderresumer.h", - "clangexceptions.cpp", - "clangexceptions.h", - "clangfilepath.cpp", - "clangfilepath.h", - "clangfilesystemwatcher.cpp", - "clangfilesystemwatcher.h", - "clangfollowsymbol.cpp", - "clangfollowsymbol.h", - "clangfollowsymboljob.cpp", - "clangfollowsymboljob.h", - "clangiasyncjob.cpp", - "clangiasyncjob.h", - "clangjobcontext.cpp", - "clangjobcontext.h", - "clangjobqueue.cpp", - "clangjobqueue.h", - "clangjobrequest.cpp", - "clangjobrequest.h", - "clangjobs.cpp", - "clangjobs.h", - "clangparsesupportivetranslationunitjob.cpp", - "clangparsesupportivetranslationunitjob.h", - "clangreferencescollector.cpp", - "clangreferencescollector.h", - "clangrequestannotationsjob.cpp", - "clangrequestannotationsjob.h", - "clangrequestreferencesjob.cpp", - "clangrequestreferencesjob.h", - "clangrequesttooltipjob.cpp", - "clangrequesttooltipjob.h", - "clangresumedocumentjob.cpp", - "clangresumedocumentjob.h", - "clangstring.h", - "clangsupportivetranslationunitinitializer.cpp", - "clangsupportivetranslationunitinitializer.h", - "clangsuspenddocumentjob.cpp", - "clangsuspenddocumentjob.h", - "clangtooltipinfocollector.cpp", - "clangtooltipinfocollector.h", - "clangtranslationunit.cpp", - "clangtranslationunit.h", - "clangtranslationunits.cpp", - "clangtranslationunits.h", - "clangtranslationunitupdater.cpp", - "clangtranslationunitupdater.h", - "clangtype.cpp", - "clangtype.h", - "clangunsavedfilesshallowarguments.cpp", - "clangunsavedfilesshallowarguments.h", - "clangupdateannotationsjob.cpp", - "clangupdateannotationsjob.h", - "clangupdateextraannotationsjob.cpp", - "clangupdateextraannotationsjob.h", - "codecompleter.cpp", - "codecompleter.h", - "codecompletionchunkconverter.cpp", - "codecompletionchunkconverter.h", - "codecompletionsextractor.cpp", - "codecompletionsextractor.h", - "commandlinearguments.cpp", - "commandlinearguments.h", - "cursor.cpp", - "cursor.h", - "diagnostic.cpp", - "diagnostic.h", - "diagnosticset.cpp", - "diagnosticset.h", - "diagnosticsetiterator.h", - "fixit.cpp", - "fixit.h", - "fulltokeninfo.cpp", - "fulltokeninfo.h", - "skippedsourceranges.cpp", - "skippedsourceranges.h", - "sourcelocation.cpp", - "sourcelocation.h", - "sourcerange.cpp", - "sourcerange.h", - "token.cpp", - "token.h", - "tokeninfo.cpp", - "tokeninfo.h", - "tokenprocessor.h", - "tokenprocessoriterator.h", - "unsavedfile.cpp", - "unsavedfile.h", - "unsavedfiles.cpp", - "unsavedfiles.h", - "utf8positionfromlinecolumn.cpp", - "utf8positionfromlinecolumn.h", - ] - } - - Group { name: "sources from clangsupport" prefix: "../../../src/libs/clangsupport/" files: [ diff --git a/tests/unit/unittest/unsavedfile-test.cpp b/tests/unit/unittest/unsavedfile-test.cpp deleted file mode 100644 index 7e4d3dae68..0000000000 --- a/tests/unit/unittest/unsavedfile-test.cpp +++ /dev/null @@ -1,234 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <clangfilepath.h> -#include <unsavedfile.h> -#include <unsavedfiles.h> - -using ClangBackEnd::FilePath; -using ClangBackEnd::UnsavedFile; -using ClangBackEnd::UnsavedFiles; - -using ::testing::Eq; -using ::testing::PrintToString; - -namespace { - -MATCHER_P3(IsUnsavedFile, fileName, contents, contentsLength, - std::string(negation ? "isn't" : "is") - + " file name " + PrintToString(fileName) - + ", contents " + PrintToString(contents) - + ", contents length " + PrintToString(contentsLength)) -{ - return fileName == arg.filePath() - && contents == arg.fileContent() - && int(contentsLength) == arg.fileContent().byteSize(); -} - -class UnsavedFile : public ::testing::Test -{ -protected: - Utf8String filePath = Utf8StringLiteral("path"); - Utf8String fileContent = Utf8StringLiteral("content"); - - Utf8String otherFilePath = Utf8StringLiteral("otherpath"); - Utf8String otherFileContent = Utf8StringLiteral("othercontent"); - - Utf8String absoluteFilePath = Utf8StringLiteral(TESTDATA_DIR"/file.cpp"); - - uint aLength = 2; - Utf8String aReplacement = Utf8StringLiteral("replacement"); -}; - -TEST_F(UnsavedFile, Create) -{ - ::UnsavedFile unsavedFile(filePath, fileContent); - - ASSERT_THAT(unsavedFile, IsUnsavedFile(filePath, - fileContent, - fileContent.byteSize())); -} - -TEST_F(UnsavedFile, CopyConstruct) -{ - ::UnsavedFile copyFrom(filePath, fileContent); - - ::UnsavedFile copyTo = copyFrom; - - ASSERT_THAT(copyTo, IsUnsavedFile(filePath, - fileContent, - fileContent.byteSize())); -} - -TEST_F(UnsavedFile, FilePath) -{ - ::UnsavedFile unsavedFile(absoluteFilePath, QStringLiteral("")); - - ASSERT_THAT(unsavedFile.filePath(), Eq(absoluteFilePath)); -} - -TEST_F(UnsavedFile, NativeFilePath) -{ - ::UnsavedFile unsavedFile(absoluteFilePath, QStringLiteral("")); - const Utf8String nativeFilePath = FilePath::toNativeSeparators(absoluteFilePath); - - ASSERT_THAT(unsavedFile.nativeFilePath(), Eq(nativeFilePath)); -} - -TEST_F(UnsavedFile, DoNotReplaceWithOffsetZeroInEmptyContent) -{ - ::UnsavedFile unsavedFile(filePath, QStringLiteral("")); - - ASSERT_FALSE(unsavedFile.replaceAt(0, aLength, aReplacement)); -} - -TEST_F(UnsavedFile, DoNotReplaceWithOffsetOneInEmptyContent) -{ - ::UnsavedFile unsavedFile(filePath, QStringLiteral("")); - - ASSERT_FALSE(unsavedFile.replaceAt(1, aLength, aReplacement)); -} - -TEST_F(UnsavedFile, Replace) -{ - const Utf8String expectedContent = Utf8StringLiteral("hello replacement!"); - ::UnsavedFile unsavedFile(filePath, Utf8StringLiteral("hello world!")); - - const bool hasReplaced = unsavedFile.replaceAt(6, 5, aReplacement); - - ASSERT_TRUE(hasReplaced); - ASSERT_THAT(unsavedFile, IsUnsavedFile(filePath, expectedContent, expectedContent.byteSize())); -} - -TEST_F(UnsavedFile, ToUtf8PositionForValidLineColumn) -{ - ::UnsavedFile unsavedFile(filePath, fileContent); - bool ok = false; - - const uint position = unsavedFile.toUtf8Position(1, 1, &ok); - - ASSERT_TRUE(ok); - ASSERT_THAT(position, Eq(0L)); -} - -TEST_F(UnsavedFile, ToUtf8PositionForInValidLineColumn) -{ - ::UnsavedFile unsavedFile(filePath, fileContent); - bool ok = false; - - unsavedFile.toUtf8Position(2, 1, &ok); - - ASSERT_FALSE(ok); -} - -TEST_F(UnsavedFile, ToUtf8PositionForDefaultConstructedUnsavedFile) -{ - ::UnsavedFile unsavedFile; - bool ok = false; - - unsavedFile.toUtf8Position(1, 1, &ok); - - ASSERT_FALSE(ok); -} - -TEST_F(UnsavedFile, HasNoCharacterForDefaultConstructedUnsavedFile) -{ - ::UnsavedFile unsavedFile; - - ASSERT_FALSE(unsavedFile.hasCharacterAt(0, 'x')); -} - -TEST_F(UnsavedFile, ReplacingInCopyDoesNotModifyOriginal) -{ - const Utf8String originalContent = Utf8StringLiteral("foo"); - ::UnsavedFile original(filePath, originalContent); - ::UnsavedFile copy = original; - - const bool hasReplaced = copy.replaceAt(0, 3, aReplacement); - - ASSERT_TRUE(hasReplaced); - ASSERT_THAT(original, IsUnsavedFile(filePath, originalContent, originalContent.byteSize())); - ASSERT_THAT(copy, IsUnsavedFile(filePath, aReplacement, aReplacement.byteSize())); -} - -TEST_F(UnsavedFile, HasNoCharacterForTooBigOffset) -{ - ::UnsavedFile unsavedFile(filePath, fileContent); - - ASSERT_FALSE(unsavedFile.hasCharacterAt(100, 'x')); -} - -TEST_F(UnsavedFile, HasNoCharacterForWrongOffset) -{ - ::UnsavedFile unsavedFile(filePath, fileContent); - - ASSERT_FALSE(unsavedFile.hasCharacterAt(0, 'x')); -} - -TEST_F(UnsavedFile, HasCharacterForCorrectOffset) -{ - ::UnsavedFile unsavedFile(filePath, fileContent); - - ASSERT_TRUE(unsavedFile.hasCharacterAt(0, 'c')); -} - -TEST_F(UnsavedFile, HasCharacterForLastLineColumn) -{ - ::UnsavedFile unsavedFile(filePath, fileContent); - - ASSERT_TRUE(unsavedFile.hasCharacterAt(1, 7, 't')); -} - -TEST_F(UnsavedFile, LineRangeForInvalidLines) -{ - ::UnsavedFile unsavedFile(filePath, fileContent); - - ASSERT_THAT(unsavedFile.lineRange(2, 1), Utf8String()); -} - -TEST_F(UnsavedFile, LineRangeForSingleLine) -{ - ::UnsavedFile unsavedFile(filePath, Utf8StringLiteral("foo")); - - ASSERT_THAT(unsavedFile.lineRange(1, 1), Utf8StringLiteral("foo")); -} - -TEST_F(UnsavedFile, LineRangeForSingleLineInMultipleLines) -{ - ::UnsavedFile unsavedFile(filePath, Utf8StringLiteral("foo\nbar\n\baz")); - - ASSERT_THAT(unsavedFile.lineRange(2, 2), Utf8StringLiteral("bar")); -} - -TEST_F(UnsavedFile, LineRangeForTwoLines) -{ - ::UnsavedFile unsavedFile(filePath, Utf8StringLiteral("foo\nbar\n\baz")); - - ASSERT_THAT(unsavedFile.lineRange(2, 3), Utf8StringLiteral("bar\n\baz")); -} - -} // anonymous namespace diff --git a/tests/unit/unittest/unsavedfiles-test.cpp b/tests/unit/unittest/unsavedfiles-test.cpp deleted file mode 100644 index 283c941d57..0000000000 --- a/tests/unit/unittest/unsavedfiles-test.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <filecontainer.h> -#include <unsavedfiles.h> -#include <unsavedfile.h> - -#include <QVector> - -using ClangBackEnd::UnsavedFile; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::FileContainer; - -using ::testing::Eq; -using ::testing::Gt; -using ::testing::IsNull; -using ::testing::Ne; -using ::testing::NotNull; -using ::testing::PrintToString; - -namespace { - -bool operator==(const ClangBackEnd::FileContainer &fileContainer, const UnsavedFile &unsavedFile) -{ - return fileContainer.filePath == unsavedFile.filePath() - && fileContainer.unsavedFileContent == unsavedFile.fileContent(); -} - -bool fileContainersContainsItemMatchingToCxUnsavedFile(const QVector<FileContainer> &fileContainers, const UnsavedFile &unsavedFile) -{ - for (const FileContainer &fileContainer : fileContainers) { - if (fileContainer == unsavedFile) - return true; - } - - return false; -} - -MATCHER_P(HasUnsavedFiles, fileContainers, "") -{ - ClangBackEnd::UnsavedFiles unsavedFiles = arg; - if (unsavedFiles.count() != uint(fileContainers.size())) { - *result_listener << "unsaved count is " << unsavedFiles.count() << " and not " << fileContainers.size(); - return false; - } - - for (uint i = 0, to = unsavedFiles.count(); i < to; ++i) { - UnsavedFile unsavedFile = unsavedFiles.at(i); - if (!fileContainersContainsItemMatchingToCxUnsavedFile(fileContainers, unsavedFile)) - return false; - } - - return true; -} - -MATCHER_P3(IsUnsavedFile, fileName, contents, contentsLength, - std::string(negation ? "isn't" : "is") - + " file name " + PrintToString(fileName) - + ", contents " + PrintToString(contents) - + ", contents length " + PrintToString(contentsLength)) -{ - return fileName == arg.filePath() - && contents == arg.fileContent() - && int(contentsLength) == arg.fileContent().byteSize(); -} - -class UnsavedFiles : public ::testing::Test -{ -protected: - ::UnsavedFiles unsavedFiles; - Utf8String filePath{Utf8StringLiteral("file.cpp")}; - - Utf8String unsavedContent1{Utf8StringLiteral("foo")}; - Utf8String unsavedContent2{Utf8StringLiteral("bar")}; -}; - -TEST_F(UnsavedFiles, ModifiedCopyIsDifferent) -{ - QVector<FileContainer> fileContainers({FileContainer(filePath, unsavedContent1, true)}); - unsavedFiles.createOrUpdate(fileContainers); - - ::UnsavedFiles copy = unsavedFiles; - QVector<FileContainer> updatedFileContainers({FileContainer(filePath, unsavedContent2, true)}); - copy.createOrUpdate(updatedFileContainers); - - ASSERT_THAT(copy.at(0).fileContent(), Ne(unsavedFiles.at(0).fileContent())); - ASSERT_THAT(copy.lastChangeTimePoint(), Gt(unsavedFiles.lastChangeTimePoint())); -} - -TEST_F(UnsavedFiles, DoNothingForUpdateIfFileHasNoUnsavedContent) -{ - QVector<FileContainer> fileContainers({FileContainer(filePath)}); - - unsavedFiles.createOrUpdate(fileContainers); - - ASSERT_THAT(unsavedFiles, HasUnsavedFiles(QVector<FileContainer>())); -} - -TEST_F(UnsavedFiles, AddUnsavedFileForUpdateWithUnsavedContent) -{ - QVector<FileContainer> fileContainers({FileContainer(filePath), - FileContainer(filePath, unsavedContent1, true)}); - unsavedFiles.createOrUpdate(fileContainers); - - ASSERT_THAT(unsavedFiles, HasUnsavedFiles(QVector<FileContainer>({FileContainer(filePath, unsavedContent1, true)}))); -} - -TEST_F(UnsavedFiles, RemoveUnsavedFileForUpdateWithUnsavedContent) -{ - QVector<FileContainer> fileContainers({FileContainer(filePath, unsavedContent1, true), - FileContainer(filePath)}); - - unsavedFiles.createOrUpdate(fileContainers); - - ASSERT_THAT(unsavedFiles, HasUnsavedFiles(QVector<FileContainer>())); -} - -TEST_F(UnsavedFiles, ExchangeUnsavedFileForUpdateWithUnsavedContent) -{ - QVector<FileContainer> fileContainers({FileContainer(filePath, unsavedContent1, true), - FileContainer(filePath, unsavedContent2, true)}); - unsavedFiles.createOrUpdate(fileContainers); - - ASSERT_THAT(unsavedFiles, HasUnsavedFiles(QVector<FileContainer>({FileContainer(filePath, unsavedContent2, true)}))); -} - -TEST_F(UnsavedFiles, TimeStampIsUpdatedAsUnsavedFilesChanged) -{ - QVector<FileContainer> fileContainers({FileContainer(filePath, unsavedContent1, true), - FileContainer(filePath, unsavedContent2, true)}); - auto lastChangeTimePoint = unsavedFiles.lastChangeTimePoint(); - - unsavedFiles.createOrUpdate(fileContainers); - - ASSERT_THAT(unsavedFiles.lastChangeTimePoint(), Gt(lastChangeTimePoint)); -} - -TEST_F(UnsavedFiles, RemoveUnsavedFiles) -{ - QVector<FileContainer> fileContainers({FileContainer(filePath, unsavedContent1, true)}); - unsavedFiles.createOrUpdate(fileContainers); - - unsavedFiles.remove(fileContainers); - - ASSERT_THAT(unsavedFiles, HasUnsavedFiles(QVector<FileContainer>())); -} - -TEST_F(UnsavedFiles, FindUnsavedFile) -{ - QVector<FileContainer> fileContainers({FileContainer(filePath, unsavedContent1, true)}); - unsavedFiles.createOrUpdate(fileContainers); - - UnsavedFile &unsavedFile = unsavedFiles.unsavedFile(filePath); - - ASSERT_THAT(unsavedFile, IsUnsavedFile(filePath, unsavedContent1, unsavedContent1.byteSize())); -} - -TEST_F(UnsavedFiles, FindNoUnsavedFile) -{ - QVector<FileContainer> fileContainers({FileContainer(filePath, unsavedContent1, true)}); - unsavedFiles.createOrUpdate(fileContainers); - - UnsavedFile &unsavedFile = unsavedFiles.unsavedFile(Utf8StringLiteral("nonExistingFilePath.cpp")); - - ASSERT_THAT(unsavedFile, IsUnsavedFile(Utf8String(), Utf8String(), 0UL)); -} - -} diff --git a/tests/unit/unittest/utf8positionfromlinecolumn-test.cpp b/tests/unit/unittest/utf8positionfromlinecolumn-test.cpp deleted file mode 100644 index 3cca681f7c..0000000000 --- a/tests/unit/unittest/utf8positionfromlinecolumn-test.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** 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. -** -****************************************************************************/ - -#include "googletest.h" - -#include <utf8positionfromlinecolumn.h> -#include <utf8string.h> - -using ClangBackEnd::Utf8PositionFromLineColumn; -using ::testing::PrintToString; - -namespace { - -class Utf8PositionFromLineColumn : public ::testing::Test -{ -protected: - Utf8String empty; - Utf8String asciiWord = Utf8StringLiteral("FOO"); - Utf8String asciiMultiLine = Utf8StringLiteral("FOO\nBAR"); - Utf8String asciiEmptyMultiLine = Utf8StringLiteral("\n\n"); - // U+00FC - 2 code units in UTF8, 1 in UTF16 - LATIN SMALL LETTER U WITH DIAERESIS - // U+4E8C - 3 code units in UTF8, 1 in UTF16 - CJK UNIFIED IDEOGRAPH-4E8C - // U+10302 - 4 code units in UTF8, 2 in UTF16 - OLD ITALIC LETTER KE - Utf8String nonAsciiMultiLine = Utf8StringLiteral("\xc3\xbc" "\n" - "\xe4\xba\x8c" "\n" - "\xf0\x90\x8c\x82" "X"); -}; - -TEST_F(Utf8PositionFromLineColumn, FindsNothingForEmptyContents) -{ - ::Utf8PositionFromLineColumn converter(empty.constData()); - - ASSERT_FALSE(converter.find(1, 1)); -} - -TEST_F(Utf8PositionFromLineColumn, FindsNothingForNoContents) -{ - ::Utf8PositionFromLineColumn converter(0); - - ASSERT_FALSE(converter.find(1, 1)); -} - -TEST_F(Utf8PositionFromLineColumn, FindsNothingForLineZero) -{ - ::Utf8PositionFromLineColumn converter(asciiWord.constData()); - - ASSERT_FALSE(converter.find(0, 1)); -} - -TEST_F(Utf8PositionFromLineColumn, FindsNothingForColumnZero) -{ - ::Utf8PositionFromLineColumn converter(asciiWord.constData()); - - ASSERT_FALSE(converter.find(1, 0)); -} - -TEST_F(Utf8PositionFromLineColumn, FindsFirstForAsciiWord) -{ - ::Utf8PositionFromLineColumn converter(asciiWord.constData()); - - ASSERT_TRUE(converter.find(1, 1)); - ASSERT_THAT(converter.position(), 0); -} - -TEST_F(Utf8PositionFromLineColumn, FindsLastForAsciiWord) -{ - ::Utf8PositionFromLineColumn converter(asciiWord.constData()); - - ASSERT_TRUE(converter.find(1, 3)); - ASSERT_THAT(converter.position(), 2); -} - -TEST_F(Utf8PositionFromLineColumn, FindsFirstForSecondLineAscii) -{ - ::Utf8PositionFromLineColumn converter(asciiMultiLine.constData()); - - ASSERT_TRUE(converter.find(2, 1)); - ASSERT_THAT(converter.position(), 4); -} - -TEST_F(Utf8PositionFromLineColumn, FindsLastForAsciiMultiLine) -{ - ::Utf8PositionFromLineColumn converter(asciiMultiLine.constData()); - - ASSERT_TRUE(converter.find(2, 3)); - ASSERT_THAT(converter.position(), 6); -} - -TEST_F(Utf8PositionFromLineColumn, FindsLastInFirstLine) -{ - ::Utf8PositionFromLineColumn converter(asciiMultiLine.constData()); - - ASSERT_TRUE(converter.find(1, 3)); - ASSERT_THAT(converter.position(), 2); -} - -TEST_F(Utf8PositionFromLineColumn, FindsNothingBeyondMaxColumn) -{ - ::Utf8PositionFromLineColumn converter(asciiWord.constData()); - - ASSERT_FALSE(converter.find(1, 4)); -} - -TEST_F(Utf8PositionFromLineColumn, FindsNothingBeyondMaxColumnForMultiLine) -{ - ::Utf8PositionFromLineColumn converter(asciiMultiLine.constData()); - - ASSERT_FALSE(converter.find(1, 4)); -} - -TEST_F(Utf8PositionFromLineColumn, FindsNothingBeyondMaxLine) -{ - ::Utf8PositionFromLineColumn converter(asciiWord.constData()); - - ASSERT_FALSE(converter.find(2, 1)); -} - -TEST_F(Utf8PositionFromLineColumn, FindsNothingForLineWithoutContent) -{ - ::Utf8PositionFromLineColumn converter(asciiEmptyMultiLine.constData()); - - ASSERT_FALSE(converter.find(1, 1)); -} - -TEST_F(Utf8PositionFromLineColumn, FindsFirstOnNonAsciiMultiLine) -{ - ::Utf8PositionFromLineColumn converter(nonAsciiMultiLine.constData()); - - ASSERT_TRUE(converter.find(1, 1)); - ASSERT_THAT(converter.position(), 0); -} - -TEST_F(Utf8PositionFromLineColumn, FindsLastOnNonAsciiMultiLine) -{ - ::Utf8PositionFromLineColumn converter(nonAsciiMultiLine.constData()); - - ASSERT_TRUE(converter.find(3, 2)); - ASSERT_THAT(converter.position(), 11); -} - -} // anonymous namespace |