diff --git a/src/libs/clangsupport/codecompletion.cpp b/src/libs/clangsupport/codecompletion.cpp index fb321d664a7..08d3416ad46 100644 --- a/src/libs/clangsupport/codecompletion.cpp +++ b/src/libs/clangsupport/codecompletion.cpp @@ -77,6 +77,8 @@ QDebug operator<<(QDebug debug, const CodeCompletion &message) debug.nospace() << message.priority << ", "; debug.nospace() << completionKindToString(message.completionKind) << ", "; debug.nospace() << availabilityToString(message.availability) << ", "; + if (!message.requiredFixIts.isEmpty()) + debug.nospace() << message.requiredFixIts << ", "; debug.nospace() << message.hasParameters; debug.nospace() << ")"; diff --git a/src/libs/clangsupport/codecompletion.h b/src/libs/clangsupport/codecompletion.h index 974b3c3f9a6..fdb637560c3 100644 --- a/src/libs/clangsupport/codecompletion.h +++ b/src/libs/clangsupport/codecompletion.h @@ -27,8 +27,9 @@ #include "clangsupport_global.h" #include "codecompletionchunk.h" +#include "fixitcontainer.h" -#include +#include #include #include @@ -90,6 +91,7 @@ public: out << message.text; out << message.briefComment; out << message.chunks; + out << message.requiredFixIts; out << message.priority; out << static_cast(message.completionKind); out << static_cast(message.availability); @@ -106,6 +108,7 @@ public: in >> message.text; in >> message.briefComment; in >> message.chunks; + in >> message.requiredFixIts; in >> message.priority; in >> completionKind; in >> availability; @@ -120,13 +123,15 @@ public: friend bool operator==(const CodeCompletion &first, const CodeCompletion &second) { return first.text == second.text - && first.completionKind == second.completionKind; + && first.completionKind == second.completionKind + && first.requiredFixIts == second.requiredFixIts; } public: Utf8String text; Utf8String briefComment; CodeCompletionChunks chunks; + QVector requiredFixIts; quint32 priority = 0; Kind completionKind = Other; Availability availability = NotAvailable; diff --git a/src/libs/clangsupport/completionsmessage.cpp b/src/libs/clangsupport/completionsmessage.cpp index b6324f6a647..d41f3dfe971 100644 --- a/src/libs/clangsupport/completionsmessage.cpp +++ b/src/libs/clangsupport/completionsmessage.cpp @@ -29,23 +29,11 @@ namespace ClangBackEnd { -#define RETURN_TEXT_FOR_CASE(enumValue) case CompletionCorrection::enumValue: return #enumValue -static const char *completionCorrectionToText(CompletionCorrection correction) -{ - switch (correction) { - RETURN_TEXT_FOR_CASE(NoCorrection); - RETURN_TEXT_FOR_CASE(DotToArrowCorrection); - default: return "UnhandledCompletionCorrection"; - } -} -#undef RETURN_TEXT_FOR_CASE - QDebug operator<<(QDebug debug, const CompletionsMessage &message) { debug.nospace() << "CompletionsMessage("; debug.nospace() << message.codeCompletions << ", " - << completionCorrectionToText(message.neededCorrection) << ", " << message.ticketNumber; debug.nospace() << ")"; diff --git a/src/libs/clangsupport/completionsmessage.h b/src/libs/clangsupport/completionsmessage.h index b77710a93b0..f23256c06fc 100644 --- a/src/libs/clangsupport/completionsmessage.h +++ b/src/libs/clangsupport/completionsmessage.h @@ -38,18 +38,15 @@ class CompletionsMessage public: CompletionsMessage() = default; CompletionsMessage(const CodeCompletions &codeCompletions, - CompletionCorrection neededCorrection, quint64 ticketNumber) : codeCompletions(codeCompletions) , ticketNumber(ticketNumber) - , neededCorrection(neededCorrection) { } friend QDataStream &operator<<(QDataStream &out, const CompletionsMessage &message) { out << message.codeCompletions; - out << static_cast(message.neededCorrection); out << message.ticketNumber; return out; @@ -57,28 +54,21 @@ public: friend QDataStream &operator>>(QDataStream &in, CompletionsMessage &message) { - quint32 neededCorrection; - in >> message.codeCompletions; - in >> neededCorrection; in >> message.ticketNumber; - message.neededCorrection = static_cast(neededCorrection); - return in; } friend bool operator==(const CompletionsMessage &first, const CompletionsMessage &second) { return first.ticketNumber == second.ticketNumber - && first.neededCorrection == second.neededCorrection && first.codeCompletions == second.codeCompletions; } public: CodeCompletions codeCompletions; quint64 ticketNumber = 0; - CompletionCorrection neededCorrection = CompletionCorrection::NoCorrection; }; CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const CompletionsMessage &message); diff --git a/src/plugins/clangcodemodel/clangassistproposal.cpp b/src/plugins/clangcodemodel/clangassistproposal.cpp deleted file mode 100644 index 16b9937908b..00000000000 --- a/src/plugins/clangcodemodel/clangassistproposal.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 "clangassistproposal.h" - -#include - -namespace ClangCodeModel { -namespace Internal { - -ClangAssistProposal::ClangAssistProposal(int cursorPos, TextEditor::GenericProposalModelPtr model) - : GenericProposal(cursorPos, model) -{ -} - -bool ClangAssistProposal::isCorrective(TextEditor::TextEditorWidget *editorWidget) const -{ - auto clangAssistProposalModel = model().staticCast(); - - return clangAssistProposalModel->neededCorrection() - == ClangBackEnd::CompletionCorrection::DotToArrowCorrection - && editorWidget->textAt(basePosition() - 1, 1) == "."; -} - -void ClangAssistProposal::makeCorrection(TextEditor::TextEditorWidget *editorWidget) -{ - const int oldPosition = editorWidget->position(); - editorWidget->setCursorPosition(basePosition() - 1); - editorWidget->replace(1, QLatin1String("->")); - editorWidget->setCursorPosition(oldPosition + 1); - moveBasePosition(1); -} - -} // namespace Internal -} // namespace ClangCodeModel - diff --git a/src/plugins/clangcodemodel/clangassistproposal.h b/src/plugins/clangcodemodel/clangassistproposal.h deleted file mode 100644 index 4353b43fb29..00000000000 --- a/src/plugins/clangcodemodel/clangassistproposal.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 "clangassistproposalmodel.h" - -#include - -namespace ClangCodeModel { -namespace Internal { - -class ClangAssistProposal : public TextEditor::GenericProposal -{ -public: - ClangAssistProposal(int cursorPos, TextEditor::GenericProposalModelPtr model); - - bool isCorrective(TextEditor::TextEditorWidget *editorWidget) const override; - void makeCorrection(TextEditor::TextEditorWidget *editorWidget) override; -}; - -} // namespace Internal -} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangassistproposalitem.cpp b/src/plugins/clangcodemodel/clangassistproposalitem.cpp index ef3b394f999..301ce193723 100644 --- a/src/plugins/clangcodemodel/clangassistproposalitem.cpp +++ b/src/plugins/clangcodemodel/clangassistproposalitem.cpp @@ -26,6 +26,7 @@ #include "clangassistproposalitem.h" #include "clangcompletionchunkstotextconverter.h" +#include "clangfixitoperation.h" #include #include @@ -35,9 +36,12 @@ #include #include +#include #include #include +#include +#include using namespace CPlusPlus; using namespace ClangBackEnd; @@ -119,7 +123,15 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface { const CodeCompletion ccr = codeCompletion(); - QString textToBeInserted = text(); + if (!ccr.requiredFixIts.empty()) { + ClangFixItOperation fixItOperation(Utf8String(), ccr.requiredFixIts); + fixItOperation.perform(); + + const int shift = fixItsShift(manipulator); + basePosition += shift; + } + + QString textToBeInserted = m_text; QString extraCharacters; int extraLength = 0; int cursorOffset = 0; @@ -269,7 +281,43 @@ void ClangAssistProposalItem::setText(const QString &text) QString ClangAssistProposalItem::text() const { - return m_text; + return m_text + (requiresFixIts() ? fixItText() : QString()); +} + +// FIXME: Indicate required fix-it without adding extra text. +QString ClangAssistProposalItem::fixItText() const +{ + const FixItContainer &fixIt = m_codeCompletion.requiredFixIts.first(); + const SourceRangeContainer &range = fixIt.range; + return QCoreApplication::translate("ClangCodeModel::ClangAssistProposalItem", + " (requires to correct [%1:%2-%3:%4] to \"%5\")") + .arg(range.start.line) + .arg(range.start.column) + .arg(range.end.line) + .arg(range.end.column) + .arg(fixIt.text.toString()); +} + +int ClangAssistProposalItem::fixItsShift( + const TextEditor::TextDocumentManipulatorInterface &manipulator) const +{ + if (m_codeCompletion.requiredFixIts.empty()) + return 0; + + int shift = 0; + QTextCursor cursor = manipulator.textCursorAt(0); + for (const FixItContainer &fixIt : m_codeCompletion.requiredFixIts) { + const int fixItStartPos = Utils::Text::positionInText( + cursor.document(), + static_cast(fixIt.range.start.line), + static_cast(fixIt.range.start.column)); + const int fixItEndPos = Utils::Text::positionInText( + cursor.document(), + static_cast(fixIt.range.end.line), + static_cast(fixIt.range.end.column)); + shift += fixIt.text.toString().length() - (fixItEndPos - fixItStartPos); + } + return shift; } QIcon ClangAssistProposalItem::icon() const @@ -362,6 +410,11 @@ quint64 ClangAssistProposalItem::hash() const return 0; } +bool ClangAssistProposalItem::requiresFixIts() const +{ + return !m_codeCompletion.requiredFixIts.empty(); +} + bool ClangAssistProposalItem::hasOverloadsWithParameters() const { return m_hasOverloadsWithParameters; diff --git a/src/plugins/clangcodemodel/clangassistproposalitem.h b/src/plugins/clangcodemodel/clangassistproposalitem.h index 90dcff35c89..02673ec53b9 100644 --- a/src/plugins/clangcodemodel/clangassistproposalitem.h +++ b/src/plugins/clangcodemodel/clangassistproposalitem.h @@ -50,6 +50,7 @@ public: bool isSnippet() const final; bool isValid() const final; quint64 hash() const final; + bool requiresFixIts() const final; void keepCompletionOperator(unsigned compOp); @@ -60,6 +61,9 @@ public: const ClangBackEnd::CodeCompletion &codeCompletion() const; private: + QString fixItText() const; + int fixItsShift(const TextEditor::TextDocumentManipulatorInterface &manipulator) const; + ClangBackEnd::CodeCompletion m_codeCompletion; QList m_overloads; bool m_hasOverloadsWithParameters = false; diff --git a/src/plugins/clangcodemodel/clangassistproposalmodel.cpp b/src/plugins/clangcodemodel/clangassistproposalmodel.cpp index 9806fd929f9..7fb13327f77 100644 --- a/src/plugins/clangcodemodel/clangassistproposalmodel.cpp +++ b/src/plugins/clangcodemodel/clangassistproposalmodel.cpp @@ -36,12 +36,6 @@ namespace Internal { constexpr int SORT_LIMIT = 30000; -ClangAssistProposalModel::ClangAssistProposalModel( - ClangBackEnd::CompletionCorrection neededCorrection) - : m_neededCorrection(neededCorrection) -{ -} - bool ClangAssistProposalModel::containsDuplicates() const { return false; @@ -62,6 +56,8 @@ void ClangAssistProposalModel::sort(const QString &/*prefix*/) return static_cast(first->prefixMatch()) < static_cast(second->prefixMatch()); } + if (first->requiresFixIts() != second->requiresFixIts()) + return first->requiresFixIts() < second->requiresFixIts(); return (first->order() > 0 && (first->order() < second->order() || (first->order() == second->order() && first->text() < second->text()))); @@ -70,11 +66,6 @@ void ClangAssistProposalModel::sort(const QString &/*prefix*/) std::sort(m_currentItems.begin(), m_currentItems.end(), currentItemsCompare); } -ClangBackEnd::CompletionCorrection ClangAssistProposalModel::neededCorrection() const -{ - return m_neededCorrection; -} - } // namespace Internal } // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/clangassistproposalmodel.h b/src/plugins/clangcodemodel/clangassistproposalmodel.h index b71d2568564..cb2cb7edd36 100644 --- a/src/plugins/clangcodemodel/clangassistproposalmodel.h +++ b/src/plugins/clangcodemodel/clangassistproposalmodel.h @@ -37,17 +37,12 @@ namespace Internal { class ClangAssistProposalModel : public TextEditor::GenericProposalModel { public: - ClangAssistProposalModel(ClangBackEnd::CompletionCorrection neededCorrection); + ClangAssistProposalModel() = default; bool containsDuplicates() const override; bool isSortable(const QString &prefix) const override; void sort(const QString &prefix) override; - - ClangBackEnd::CompletionCorrection neededCorrection() const; - -private: - ClangBackEnd::CompletionCorrection m_neededCorrection; }; } // namespace Internal diff --git a/src/plugins/clangcodemodel/clangbackendreceiver.cpp b/src/plugins/clangcodemodel/clangbackendreceiver.cpp index d340a990d31..7218695d613 100644 --- a/src/plugins/clangcodemodel/clangbackendreceiver.cpp +++ b/src/plugins/clangcodemodel/clangbackendreceiver.cpp @@ -187,10 +187,8 @@ void BackendReceiver::completions(const CompletionsMessage &message) const quint64 ticket = message.ticketNumber; QScopedPointer processor(m_assistProcessorsTable.take(ticket)); - if (processor) { - processor->handleAvailableCompletions(message.codeCompletions, - message.neededCorrection); - } + if (processor) + processor->handleAvailableCompletions(message.codeCompletions); } void BackendReceiver::annotations(const AnnotationsMessage &message) diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index decfacf8bdc..fd64057effe 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -8,7 +8,6 @@ requires(!isEmpty(LLVM_VERSION)) SOURCES += \ clangactivationsequencecontextprocessor.cpp \ clangactivationsequenceprocessor.cpp \ - clangassistproposal.cpp \ clangassistproposalitem.cpp \ clangassistproposalmodel.cpp \ clangbackendcommunicator.cpp \ @@ -46,7 +45,6 @@ SOURCES += \ HEADERS += \ clangactivationsequencecontextprocessor.h \ clangactivationsequenceprocessor.h \ - clangassistproposal.h \ clangassistproposalitem.h \ clangassistproposalmodel.h \ clangbackendcommunicator.h \ diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index ce1cba0e1fa..ea494fca2bb 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -36,8 +36,6 @@ QtcPlugin { "clangactivationsequencecontextprocessor.h", "clangactivationsequenceprocessor.cpp", "clangactivationsequenceprocessor.h", - "clangassistproposal.cpp", - "clangassistproposal.h", "clangassistproposalitem.cpp", "clangassistproposalitem.h", "clangassistproposalmodel.cpp", diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index 974b2d3e86a..76c0634d5ce 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -26,7 +26,6 @@ #include "clangassistproposalitem.h" #include "clangactivationsequenceprocessor.h" -#include "clangassistproposal.h" #include "clangassistproposalmodel.h" #include "clangcompletionassistprocessor.h" #include "clangcompletioncontextanalyzer.h" @@ -41,6 +40,7 @@ #include #include +#include #include #include @@ -68,7 +68,6 @@ namespace { QList toAssistProposalItems(const CodeCompletions &completions) { - bool signalCompletion = false; // TODO bool slotCompletion = false; // TODO @@ -143,8 +142,7 @@ static CodeCompletions filterFunctionSignatures(const CodeCompletions &completio } void ClangCompletionAssistProcessor::handleAvailableCompletions( - const CodeCompletions &completions, - CompletionCorrection neededCorrection) + const CodeCompletions &completions) { QTC_CHECK(m_completions.isEmpty()); @@ -154,7 +152,7 @@ void ClangCompletionAssistProcessor::handleAvailableCompletions( if (m_addSnippets && !m_completions.isEmpty()) addSnippets(); - setAsyncProposalAvailable(createProposal(neededCorrection)); + setAsyncProposalAvailable(createProposal()); } else { const CodeCompletions functionSignatures = filterFunctionSignatures(completions); if (!functionSignatures.isEmpty()) @@ -591,13 +589,12 @@ bool ClangCompletionAssistProcessor::sendCompletionRequest(int position, return false; } -TextEditor::IAssistProposal *ClangCompletionAssistProcessor::createProposal( - CompletionCorrection neededCorrection) +TextEditor::IAssistProposal *ClangCompletionAssistProcessor::createProposal() { m_requestSent = false; - TextEditor::GenericProposalModelPtr model(new ClangAssistProposalModel(neededCorrection)); + TextEditor::GenericProposalModelPtr model(new ClangAssistProposalModel()); model->loadContent(m_completions); - return new ClangAssistProposal(m_positionForProposal, model); + return new GenericProposal(m_positionForProposal, model); } IAssistProposal *ClangCompletionAssistProcessor::createFunctionHintProposal( diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.h b/src/plugins/clangcodemodel/clangcompletionassistprocessor.h index d406422aa32..f5f7b06684c 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.h +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.h @@ -50,8 +50,7 @@ public: TextEditor::IAssistProposal *perform(const TextEditor::AssistInterface *interface) override; - void handleAvailableCompletions(const CodeCompletions &completions, - CompletionCorrection neededCorrection); + void handleAvailableCompletions(const CodeCompletions &completions); bool running() final { return m_requestSent; } const TextEditor::TextEditorWidget *textEditorWidget() const; @@ -62,8 +61,7 @@ private: int findStartOfName(int pos = -1) const; bool accepts() const; - TextEditor::IAssistProposal *createProposal( - CompletionCorrection neededCorrection = CompletionCorrection::NoCorrection); + TextEditor::IAssistProposal *createProposal(); TextEditor::IAssistProposal *createFunctionHintProposal( const CodeCompletions &completions); diff --git a/src/plugins/texteditor/codeassist/assistproposaliteminterface.h b/src/plugins/texteditor/codeassist/assistproposaliteminterface.h index a4f925f4d90..12b925ebf57 100644 --- a/src/plugins/texteditor/codeassist/assistproposaliteminterface.h +++ b/src/plugins/texteditor/codeassist/assistproposaliteminterface.h @@ -65,6 +65,7 @@ public: virtual bool isSnippet() const = 0; virtual bool isValid() const = 0; virtual quint64 hash() const = 0; // it is only for removing duplicates + virtual bool requiresFixIts() const { return false; } inline int order() const { return m_order; } inline void setOrder(int order) { m_order = order; } diff --git a/src/tools/clangbackend/source/clangbackend_global.h b/src/tools/clangbackend/source/clangbackend_global.h index ff25ddeb818..658e2e8fb1b 100644 --- a/src/tools/clangbackend/source/clangbackend_global.h +++ b/src/tools/clangbackend/source/clangbackend_global.h @@ -56,4 +56,9 @@ enum class PreferredTranslationUnit # define IS_SKIPWARNINGSFROMINCLUDEDFILES_SUPPORTED #endif +// CLANG-UPGRADE-CHECK: Remove IS_COMPLETION_FIXITS_BACKPORTED once we require clang >= 7.0 +#if defined(CINDEX_VERSION_HAS_COMPLETION_FIXITS_BACKPORTED) || CINDEX_VERSION_MINOR >= 49 +# define IS_COMPLETION_FIXITS_BACKPORTED +#endif + } // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/clangcompletecodejob.cpp b/src/tools/clangbackend/source/clangcompletecodejob.cpp index 50635a6f0dd..ad033a9ea5d 100644 --- a/src/tools/clangbackend/source/clangcompletecodejob.cpp +++ b/src/tools/clangbackend/source/clangcompletecodejob.cpp @@ -50,13 +50,9 @@ IAsyncJob::AsyncPrepareResult CompleteCodeJob::prepareAsyncRun() TIME_SCOPE_DURATION("CompleteCodeJobRunner"); UnsavedFiles theUnsavedFiles = unsavedFiles; - const TranslationUnit::CodeCompletionResult results - = translationUnit.complete(theUnsavedFiles, line, column, - funcNameStartLine, funcNameStartColumn); - CompleteCodeJob::AsyncResult asyncResult; - asyncResult.completions = results.completions; - asyncResult.correction = results.correction; + asyncResult = translationUnit.complete(theUnsavedFiles, line, column, + funcNameStartLine, funcNameStartColumn); return asyncResult; }); @@ -69,9 +65,7 @@ void CompleteCodeJob::finalizeAsyncRun() if (context().isDocumentOpen()) { const AsyncResult result = asyncResult(); - const CompletionsMessage message(result.completions, - result.correction, - context().jobRequest.ticketNumber); + const CompletionsMessage message(result, context().jobRequest.ticketNumber); context().client->completions(message); } } diff --git a/src/tools/clangbackend/source/clangcompletecodejob.h b/src/tools/clangbackend/source/clangcompletecodejob.h index 4e9c274faf9..0d62ce8b946 100644 --- a/src/tools/clangbackend/source/clangcompletecodejob.h +++ b/src/tools/clangbackend/source/clangcompletecodejob.h @@ -31,16 +31,10 @@ namespace ClangBackEnd { -struct CompleteCodeJobResult -{ - CodeCompletions completions; - CompletionCorrection correction = CompletionCorrection::NoCorrection; -}; - -class CompleteCodeJob : public DocumentJob +class CompleteCodeJob : public DocumentJob { public: - using AsyncResult = CompleteCodeJobResult; + using AsyncResult = CodeCompletions; AsyncPrepareResult prepareAsyncRun() override; void finalizeAsyncRun() override; diff --git a/src/tools/clangbackend/source/clangjobrequest.cpp b/src/tools/clangbackend/source/clangjobrequest.cpp index 6d73e829968..adaa3201231 100644 --- a/src/tools/clangbackend/source/clangjobrequest.cpp +++ b/src/tools/clangbackend/source/clangjobrequest.cpp @@ -268,8 +268,7 @@ void JobRequest::cancelJob(ClangCodeModelClientInterface &client) const client.tooltip(ToolTipMessage(FileContainer(), ToolTipInfo(), ticketNumber)); break; case JobRequest::Type::RequestCompletions: - client.completions( - CompletionsMessage(CodeCompletions(), CompletionCorrection::NoCorrection, ticketNumber)); + client.completions(CompletionsMessage(CodeCompletions(), ticketNumber)); break; case JobRequest::Type::RequestFollowSymbol: client.followSymbol( diff --git a/src/tools/clangbackend/source/clangtranslationunit.cpp b/src/tools/clangbackend/source/clangtranslationunit.cpp index 017abdd98f0..ad242c7be85 100644 --- a/src/tools/clangbackend/source/clangtranslationunit.cpp +++ b/src/tools/clangbackend/source/clangtranslationunit.cpp @@ -111,21 +111,11 @@ bool TranslationUnit::suspend() const return clang_suspendTranslationUnit(cxTranslationUnit()); } -TranslationUnit::CodeCompletionResult TranslationUnit::complete( - UnsavedFiles &unsavedFiles, - uint line, - uint column, - int funcNameStartLine, - int funcNameStartColumn) const +CodeCompletions TranslationUnit::complete(UnsavedFiles &unsavedFiles, uint line, uint column, + int funcNameStartLine, int funcNameStartColumn) const { - CodeCompleter codeCompleter(*this, unsavedFiles); - - const CodeCompletions completions = codeCompleter.complete(line, column, - funcNameStartLine, - funcNameStartColumn); - const CompletionCorrection correction = codeCompleter.neededCorrection(); - - return CodeCompletionResult{completions, correction}; + return CodeCompleter(*this, unsavedFiles).complete(line, column, funcNameStartLine, + funcNameStartColumn); } void TranslationUnit::extractAnnotations( diff --git a/src/tools/clangbackend/source/clangtranslationunit.h b/src/tools/clangbackend/source/clangtranslationunit.h index ae8741a9890..83c8d196a6a 100644 --- a/src/tools/clangbackend/source/clangtranslationunit.h +++ b/src/tools/clangbackend/source/clangtranslationunit.h @@ -51,12 +51,6 @@ class CommandLineArguments; class TranslationUnit { -public: - struct CodeCompletionResult { - CodeCompletions completions; - CompletionCorrection correction; - }; - public: TranslationUnit(const Utf8String &id, const Utf8String &filePath, @@ -77,8 +71,8 @@ public: TranslationUnitUpdateResult parse(const TranslationUnitUpdateInput &parseInput) const; TranslationUnitUpdateResult reparse(const TranslationUnitUpdateInput &parseInput) const; - CodeCompletionResult complete(UnsavedFiles &unsavedFiles, uint line, uint column, - int funcNameStartLine, int funcNameStartColumn) const; + CodeCompletions complete(UnsavedFiles &unsavedFiles, uint line, uint column, + int funcNameStartLine, int funcNameStartColumn) const; void extractDiagnostics(DiagnosticContainer &firstHeaderErrorDiagnostic, QVector &mainFileDiagnostics) const; diff --git a/src/tools/clangbackend/source/codecompleter.cpp b/src/tools/clangbackend/source/codecompleter.cpp index 8fa5c9cce23..a764d2ae5aa 100644 --- a/src/tools/clangbackend/source/codecompleter.cpp +++ b/src/tools/clangbackend/source/codecompleter.cpp @@ -25,19 +25,20 @@ #include "codecompleter.h" -#include "clangfilepath.h" +#include "clangbackend_global.h" #include "clangcodecompleteresults.h" -#include "clangstring.h" -#include "cursor.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 "clangdocument.h" -#include "sourcerange.h" -#include "clangunsavedfilesshallowarguments.h" -#include "clangtranslationunitupdater.h" #include @@ -45,12 +46,13 @@ namespace ClangBackEnd { namespace { -CodeCompletions toCodeCompletions(const ClangCodeCompleteResults &results) +CodeCompletions toCodeCompletions(const TranslationUnit &translationUnit, + const ClangCodeCompleteResults &results) { if (results.isNull()) return CodeCompletions(); - CodeCompletionsExtractor extractor(results.data()); + CodeCompletionsExtractor extractor(translationUnit.cxTranslationUnit(), results.data()); CodeCompletions codeCompletions = extractor.extractAll(); return codeCompletions; @@ -85,8 +87,6 @@ CodeCompletions CodeCompleter::complete(uint line, uint column, int funcNameStartLine, int funcNameStartColumn) { - neededCorrection_ = CompletionCorrection::NoCorrection; - // 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 results = completeSmartPointerCreation(line, @@ -98,14 +98,8 @@ CodeCompletions CodeCompleter::complete(uint line, uint column, results = completeHelper(line, column); filterUnknownContextResults(results, unsavedFile(), line, column); - tryDotArrowCorrectionIfNoResults(results, line, column); - return toCodeCompletions(results); -} - -CompletionCorrection CodeCompleter::neededCorrection() const -{ - return neededCorrection_; + return toCodeCompletions(translationUnit, results); } // For given "make_unique" / "make_shared" / "QSharedPointer::create" return "new T(" @@ -181,7 +175,10 @@ ClangCodeCompleteResults CodeCompleter::completeHelper(uint line, uint column) uint CodeCompleter::defaultOptions() const { uint options = CXCodeComplete_IncludeMacros - | CXCodeComplete_IncludeCodePatterns; + #ifdef IS_COMPLETION_FIXITS_BACKPORTED + | CXCodeComplete_IncludeCompletionsWithFixIts + #endif + | CXCodeComplete_IncludeCodePatterns; if (TranslationUnitUpdater::defaultParseOptions() & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion) { @@ -196,37 +193,5 @@ UnsavedFile &CodeCompleter::unsavedFile() return unsavedFiles.unsavedFile(translationUnit.filePath()); } -void CodeCompleter::tryDotArrowCorrectionIfNoResults(ClangCodeCompleteResults &results, - uint line, - uint column) -{ - if (results.hasNoResultsForDotCompletion()) { - const UnsavedFile &theUnsavedFile = unsavedFile(); - bool positionIsOk = false; - const uint dotPosition = theUnsavedFile.toUtf8Position(line, column - 1, &positionIsOk); - if (positionIsOk && theUnsavedFile.hasCharacterAt(dotPosition, '.')) - results = completeWithArrowInsteadOfDot(line, column, dotPosition); - } -} - -ClangCodeCompleteResults CodeCompleter::completeWithArrowInsteadOfDot(uint line, - uint column, - uint dotPosition) -{ - ClangCodeCompleteResults results; - const bool replaced = unsavedFile().replaceAt(dotPosition, - 1, - Utf8StringLiteral("->")); - - if (replaced) { - results = completeHelper(line, column + 1); - if (results.hasResults()) - neededCorrection_ = CompletionCorrection::DotToArrowCorrection; - filterUnknownContextResults(results, unsavedFile(), line, column+1); - } - - return results; -} - } // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/codecompleter.h b/src/tools/clangbackend/source/codecompleter.h index 2026e9ba2c0..6bfe77c09d5 100644 --- a/src/tools/clangbackend/source/codecompleter.h +++ b/src/tools/clangbackend/source/codecompleter.h @@ -47,29 +47,19 @@ public: int funcNameStartLine = -1, int funcNameStartColumn = -1); - CompletionCorrection neededCorrection() const; - private: uint defaultOptions() const; UnsavedFile &unsavedFile(); - void tryDotArrowCorrectionIfNoResults(ClangCodeCompleteResults &results, - uint line, - uint column); - ClangCodeCompleteResults completeHelper(uint line, uint column); ClangCodeCompleteResults completeSmartPointerCreation(uint line, uint column, int funcNameStartLine, int funcNameStartColumn); - ClangCodeCompleteResults completeWithArrowInsteadOfDot(uint line, - uint column, - uint dotPosition); private: TranslationUnit translationUnit; UnsavedFiles unsavedFiles; - CompletionCorrection neededCorrection_ = CompletionCorrection::NoCorrection; }; } // namespace ClangBackEnd diff --git a/src/tools/clangbackend/source/codecompletionsextractor.cpp b/src/tools/clangbackend/source/codecompletionsextractor.cpp index c1e0fdeb718..014116102c4 100644 --- a/src/tools/clangbackend/source/codecompletionsextractor.cpp +++ b/src/tools/clangbackend/source/codecompletionsextractor.cpp @@ -25,15 +25,19 @@ #include "codecompletionsextractor.h" +#include "clangbackend_global.h" #include "clangstring.h" #include "codecompletionchunkconverter.h" +#include "sourcerange.h" #include namespace ClangBackEnd { -CodeCompletionsExtractor::CodeCompletionsExtractor(CXCodeCompleteResults *cxCodeCompleteResults) - : cxCodeCompleteResults(cxCodeCompleteResults) +CodeCompletionsExtractor::CodeCompletionsExtractor(CXTranslationUnit cxTranslationUnit, + CXCodeCompleteResults *cxCodeCompleteResults) + : cxTranslationUnit(cxTranslationUnit) + , cxCodeCompleteResults(cxCodeCompleteResults) { } @@ -55,6 +59,7 @@ bool CodeCompletionsExtractor::next() extractBriefComment(); extractCompletionChunks(); adaptPriority(); + extractRequiredFixIts(); ++cxCodeCompleteResultIndex; @@ -260,6 +265,27 @@ void CodeCompletionsExtractor::extractCompletionChunks() currentCodeCompletion_.chunks = CodeCompletionChunkConverter::extract(currentCxCodeCompleteResult.CompletionString); } +void CodeCompletionsExtractor::extractRequiredFixIts() +{ +#ifdef IS_COMPLETION_FIXITS_BACKPORTED + 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), SourceRange(cxTranslationUnit, range))); + } +#endif +} + void CodeCompletionsExtractor::adaptPriority() { decreasePriorityForDestructors(); diff --git a/src/tools/clangbackend/source/codecompletionsextractor.h b/src/tools/clangbackend/source/codecompletionsextractor.h index bbb3611bf65..1c5f963c14b 100644 --- a/src/tools/clangbackend/source/codecompletionsextractor.h +++ b/src/tools/clangbackend/source/codecompletionsextractor.h @@ -38,7 +38,8 @@ namespace ClangBackEnd { class CodeCompletionsExtractor { public: - CodeCompletionsExtractor(CXCodeCompleteResults *cxCodeCompleteResults); + CodeCompletionsExtractor(CXTranslationUnit cxTranslationUnit, + CXCodeCompleteResults *cxCodeCompleteResults); CodeCompletionsExtractor(CodeCompletionsExtractor&) = delete; CodeCompletionsExtractor &operator=(CodeCompletionsExtractor&) = delete; @@ -63,6 +64,7 @@ private: void extractHasParameters(); void extractBriefComment(); void extractCompletionChunks(); + void extractRequiredFixIts(); void adaptPriority(); void decreasePriorityForNonAvailableCompletions(); @@ -75,6 +77,7 @@ private: private: CodeCompletion currentCodeCompletion_; + CXTranslationUnit cxTranslationUnit; CXCompletionResult currentCxCodeCompleteResult; CXCodeCompleteResults *cxCodeCompleteResults; uint cxCodeCompleteResultIndex = 0; diff --git a/tests/unit/unittest/clientserverinprocess-test.cpp b/tests/unit/unittest/clientserverinprocess-test.cpp index 68dd598e593..4e201fdcee9 100644 --- a/tests/unit/unittest/clientserverinprocess-test.cpp +++ b/tests/unit/unittest/clientserverinprocess-test.cpp @@ -176,9 +176,7 @@ TEST_F(ClientServerInProcess, SendRequestAnnotationsMessage) TEST_F(ClientServerInProcess, SendCompletionsMessage) { ClangBackEnd::CodeCompletions codeCompletions({Utf8StringLiteral("newFunction()")}); - ClangBackEnd::CompletionsMessage message(codeCompletions, - ClangBackEnd::CompletionCorrection::NoCorrection, - 1); + ClangBackEnd::CompletionsMessage message(codeCompletions, 1); EXPECT_CALL(mockClangCodeModelClient, completions(message)) .Times(1); diff --git a/tests/unit/unittest/codecompleter-test.cpp b/tests/unit/unittest/codecompleter-test.cpp index c55a9a0514a..ed07ecdc04f 100644 --- a/tests/unit/unittest/codecompleter-test.cpp +++ b/tests/unit/unittest/codecompleter-test.cpp @@ -67,6 +67,11 @@ MATCHER_P2(IsCodeCompletion, text, completionKind, return true; } +MATCHER(HasFixIts, "") +{ + return !arg.requiredFixIts.empty(); +} + class CodeCompleter : public ::testing::Test { protected: @@ -372,8 +377,7 @@ TEST_F(CodeCompleterSlowTest, ArrowCompletion) ASSERT_THAT(completions, Contains(IsCodeCompletion(Utf8StringLiteral("member"), CodeCompletion::VariableCompletionKind))); - ASSERT_THAT(myCompleter.neededCorrection(), - ClangBackEnd::CompletionCorrection::NoCorrection); + ASSERT_THAT(completions, Not(Contains(HasFixIts()))); } TEST_F(CodeCompleterSlowTest, DotToArrowCompletionForPointer) @@ -385,8 +389,7 @@ TEST_F(CodeCompleterSlowTest, DotToArrowCompletionForPointer) ASSERT_THAT(completions, Contains(IsCodeCompletion(Utf8StringLiteral("member"), CodeCompletion::VariableCompletionKind))); - ASSERT_THAT(myCompleter.neededCorrection(), - ClangBackEnd::CompletionCorrection::DotToArrowCorrection); + ASSERT_THAT(completions, Contains(HasFixIts())); } TEST_F(CodeCompleterSlowTest, DotToArrowCompletionForPointerInOutdatedDocument) @@ -406,8 +409,7 @@ TEST_F(CodeCompleterSlowTest, DotToArrowCompletionForPointerInOutdatedDocument) ASSERT_THAT(completions, Contains(IsCodeCompletion(Utf8StringLiteral("member"), CodeCompletion::VariableCompletionKind))); - ASSERT_THAT(myCompleter.neededCorrection(), - ClangBackEnd::CompletionCorrection::DotToArrowCorrection); + ASSERT_THAT(completions, Contains(HasFixIts())); } TEST_F(CodeCompleterSlowTest, NoDotToArrowCompletionForObject) @@ -419,7 +421,7 @@ TEST_F(CodeCompleterSlowTest, NoDotToArrowCompletionForObject) ASSERT_THAT(completions, Contains(IsCodeCompletion(Utf8StringLiteral("member"), CodeCompletion::VariableCompletionKind))); - ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection); + ASSERT_THAT(completions, Not(Contains(HasFixIts()))); } TEST_F(CodeCompleterSlowTest, NoDotToArrowCompletionForFloat) @@ -429,7 +431,6 @@ TEST_F(CodeCompleterSlowTest, NoDotToArrowCompletionForFloat) const ClangBackEnd::CodeCompletions completions = myCompleter.complete(3, 18); ASSERT_TRUE(completions.isEmpty()); - ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection); } TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForObjectWithArrowOperator) @@ -441,7 +442,7 @@ TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForObjectWithArrowOperator) ASSERT_THAT(completions, Contains(IsCodeCompletion(Utf8StringLiteral("member"), CodeCompletion::VariableCompletionKind))); - ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection); + ASSERT_THAT(completions, Not(Contains(HasFixIts()))); } TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForDotDot) @@ -451,7 +452,6 @@ TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForDotDot) const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 10); ASSERT_TRUE(completions.isEmpty()); - ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection); } TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForArrowDot) @@ -461,7 +461,6 @@ TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForArrowDot) const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 11); ASSERT_TRUE(completions.isEmpty()); - ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection); } TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForOnlyDot) @@ -471,7 +470,6 @@ TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForOnlyDot) const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 6); ASSERT_TRUE(completions.isEmpty()); - ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection); } TEST_F(CodeCompleterSlowTest, GlobalCompletionForSpaceAfterOnlyDot) @@ -489,16 +487,7 @@ TEST_F(CodeCompleterSlowTest, NoDotArrowCorrectionForColonColon) auto myCompleter = setupCompleter(noDotArrowCorrectionForColonColonFileContainer); const ClangBackEnd::CodeCompletions completions = myCompleter.complete(1, 7); - ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection); -} - -TEST_F(CodeCompleterSlowTest, DotArrowCorrectionForForwardDeclaredClassPointer) -{ - auto myCompleter = setupCompleter(dotArrowCorrectionForForwardDeclaredClassPointer); - const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 9); - - ASSERT_TRUE(completions.isEmpty()); - ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::DotToArrowCorrection); + ASSERT_THAT(completions, Not(Contains(HasFixIts()))); } TEST_F(CodeCompleterSlowTest, NoGlobalCompletionAfterForwardDeclaredClassPointer) @@ -507,7 +496,6 @@ TEST_F(CodeCompleterSlowTest, NoGlobalCompletionAfterForwardDeclaredClassPointer const ClangBackEnd::CodeCompletions completions = myCompleter.complete(5, 10); ASSERT_TRUE(completions.isEmpty()); - ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection); } TEST_F(CodeCompleterSlowTest, GlobalCompletionAfterForwardDeclaredClassPointer) @@ -516,7 +504,6 @@ TEST_F(CodeCompleterSlowTest, GlobalCompletionAfterForwardDeclaredClassPointer) const ClangBackEnd::CodeCompletions completions = myCompleter.complete(6, 4); ASSERT_TRUE(!completions.isEmpty()); - ASSERT_THAT(myCompleter.neededCorrection(), ClangBackEnd::CompletionCorrection::NoCorrection); } ClangBackEnd::CodeCompleter CodeCompleter::setupCompleter( diff --git a/tests/unit/unittest/codecompletionsextractor-test.cpp b/tests/unit/unittest/codecompletionsextractor-test.cpp index 553392700fc..308582dd41f 100644 --- a/tests/unit/unittest/codecompletionsextractor-test.cpp +++ b/tests/unit/unittest/codecompletionsextractor-test.cpp @@ -169,7 +169,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Function) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Function"), CodeCompletion::FunctionCompletionKind, @@ -180,7 +182,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, TemplateFunction) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("TemplateFunction"), CodeCompletion::TemplateFunctionCompletionKind, @@ -191,7 +195,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Variable) { ClangCodeCompleteResults completeResults(getResults(variableDocument, 4)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + variableDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Var"), CodeCompletion::VariableCompletionKind, @@ -202,7 +208,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, NonTypeTemplateParameter) { ClangCodeCompleteResults completeResults(getResults(variableDocument, 25, 19)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + variableDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("NonTypeTemplateParameter"), CodeCompletion::VariableCompletionKind, @@ -214,7 +222,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, VariableReference) { ClangCodeCompleteResults completeResults(getResults(variableDocument, 12)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + variableDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Var"), CodeCompletion::VariableCompletionKind, @@ -225,7 +235,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Parameter) { ClangCodeCompleteResults completeResults(getResults(variableDocument, 4)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + variableDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Parameter"), CodeCompletion::VariableCompletionKind, @@ -236,7 +248,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Field) { ClangCodeCompleteResults completeResults(getResults(variableDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + variableDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Field"), CodeCompletion::VariableCompletionKind, @@ -247,7 +261,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Class) { ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + classDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Class"), CodeCompletion::ClassCompletionKind, @@ -258,7 +274,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Struct) { ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + classDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Struct"), CodeCompletion::ClassCompletionKind, @@ -269,7 +287,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Union) { ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + classDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Union"), CodeCompletion::ClassCompletionKind, @@ -280,7 +300,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Typedef) { ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + classDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("TypeDef"), CodeCompletion::TypeAliasCompletionKind, @@ -291,7 +313,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, UsingAsTypeAlias) { ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + classDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("UsingClass"), CodeCompletion::TypeAliasCompletionKind, @@ -302,7 +326,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, TemplateTypeParameter) { ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + classDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("TemplateTypeParameter"), CodeCompletion::ClassCompletionKind, @@ -313,7 +339,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, TemplateClass) { ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + classDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("TemplateClass"), CodeCompletion::TemplateClassCompletionKind, @@ -324,7 +352,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, TemplateTemplateParameter) { ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + classDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("TemplateTemplateParameter"), CodeCompletion::TemplateClassCompletionKind, @@ -335,7 +365,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, ClassTemplatePartialSpecialization) { ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + classDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("ClassTemplatePartialSpecialization"), CodeCompletion::TemplateClassCompletionKind, @@ -346,7 +378,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Namespace) { ClangCodeCompleteResults completeResults(getResults(namespaceDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + namespaceDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Namespace"), CodeCompletion::NamespaceCompletionKind, @@ -357,7 +391,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, NamespaceAlias) { ClangCodeCompleteResults completeResults(getResults(namespaceDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + namespaceDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("NamespaceAlias"), CodeCompletion::NamespaceCompletionKind, @@ -368,7 +404,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Enumeration) { ClangCodeCompleteResults completeResults(getResults(enumerationDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + enumerationDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Enumeration"), CodeCompletion::EnumerationCompletionKind, @@ -379,7 +417,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Enumerator) { ClangCodeCompleteResults completeResults(getResults(enumerationDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + enumerationDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Enumerator"), CodeCompletion::EnumeratorCompletionKind, @@ -390,7 +430,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Constructor) { ClangCodeCompleteResults completeResults(getResults(constructorDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + constructorDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Constructor"), CodeCompletion::ConstructorCompletionKind, @@ -401,7 +443,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Destructor) { ClangCodeCompleteResults completeResults(getResults(constructorDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + constructorDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("~Constructor"), CodeCompletion::DestructorCompletionKind, @@ -412,7 +456,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Method) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Method"), CodeCompletion::FunctionCompletionKind, @@ -424,7 +470,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, MethodWithParameters) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("MethodWithParameters"), CodeCompletion::FunctionCompletionKind, @@ -436,7 +484,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Slot) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Slot"), CodeCompletion::SlotCompletionKind, @@ -447,7 +497,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, Signal) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Signal"), CodeCompletion::SignalCompletionKind, @@ -458,7 +510,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, MacroDefinition) { ClangCodeCompleteResults completeResults(getResults(variableDocument, 35)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + variableDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("MacroDefinition"), CodeCompletion::PreProcessorCompletionKind, @@ -469,7 +523,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, FunctionMacro) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("FunctionMacro"), CodeCompletion::FunctionCompletionKind, @@ -480,7 +536,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, IntKeyword) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("int"), CodeCompletion::KeywordCompletionKind, @@ -491,7 +549,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, SwitchKeyword) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("switch"), CodeCompletion::KeywordCompletionKind, @@ -502,7 +562,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, ClassKeyword) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("class"), CodeCompletion::KeywordCompletionKind, @@ -513,7 +575,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, DeprecatedFunction) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("DeprecatedFunction"), CodeCompletion::FunctionCompletionKind, @@ -524,7 +588,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, NotAccessibleFunction) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("NotAccessibleFunction"), CodeCompletion::FunctionCompletionKind, @@ -535,7 +601,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, NotAvailableFunction) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("NotAvailableFunction"), CodeCompletion::FunctionCompletionKind, @@ -549,7 +617,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, UnsavedFile) TESTDATA_DIR"/complete_extractor_function_unsaved.cpp")}); ClangCodeCompleteResults completeResults(getResults(document, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + document.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Method2"), CodeCompletion::FunctionCompletionKind, @@ -566,7 +636,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, ChangeUnsavedFile) TESTDATA_DIR"/complete_extractor_function_unsaved_2.cpp")}); completeResults = getResults(document, 20); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + document.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Method3"), CodeCompletion::FunctionCompletionKind, @@ -578,7 +650,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, ArgumentDefinition) project.setArguments({Utf8StringLiteral("-DArgumentDefinition"), Utf8StringLiteral("-std=gnu++14")}); ClangCodeCompleteResults completeResults(getResults(variableDocument, 35)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + variableDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("ArgumentDefinitionVariable"), CodeCompletion::VariableCompletionKind, @@ -590,7 +664,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, NoArgumentDefinition) project.setArguments({Utf8StringLiteral("-std=gnu++14")}); ClangCodeCompleteResults completeResults(getResults(variableDocument, 35)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + variableDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, Not(HasCompletion(Utf8StringLiteral("ArgumentDefinitionVariable"), CodeCompletion::VariableCompletionKind, @@ -601,7 +677,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksFunction) { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("Function"), CodeCompletionChunks({{CodeCompletionChunk::ResultType, Utf8StringLiteral("void")}, @@ -614,7 +692,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksFunctionWithOptionalChu { ClangCodeCompleteResults completeResults(getResults(functionDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("FunctionWithOptional"), CodeCompletionChunks({{CodeCompletionChunk::ResultType, Utf8StringLiteral("void")}, @@ -632,7 +712,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksField) { ClangCodeCompleteResults completeResults(getResults(variableDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + variableDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("Field"), CodeCompletionChunks({{CodeCompletionChunk::ResultType, Utf8StringLiteral("int")}, @@ -643,7 +725,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksEnumerator) { ClangCodeCompleteResults completeResults(getResults(enumerationDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + enumerationDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("Enumerator"), CodeCompletionChunks({{CodeCompletionChunk::ResultType, Utf8StringLiteral("Enumeration")}, @@ -654,7 +738,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksEnumeration) { ClangCodeCompleteResults completeResults(getResults(enumerationDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + enumerationDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("Enumeration"), CodeCompletionChunks({{CodeCompletionChunk::TypedText, Utf8StringLiteral("Enumeration")}}))); @@ -664,7 +750,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, CompletionChunksClass) { ClangCodeCompleteResults completeResults(getResults(classDocument, 20)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + classDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletionChunks(Utf8StringLiteral("Class"), CodeCompletionChunks({{CodeCompletionChunk::TypedText, Utf8StringLiteral("Class")}}))); @@ -675,7 +763,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, BriefComment) ClangCodeCompleteResults completeResults(getResults(briefCommentDocument, 10, 1, /*needsReparse=*/ true)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + briefCommentDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasBriefComment(Utf8StringLiteral("BriefComment"), Utf8StringLiteral("A brief comment"))); } @@ -684,7 +774,9 @@ TEST_F(CodeCompletionsExtractorSlowTest, OverloadCandidate) { ClangCodeCompleteResults completeResults(getResults(functionOverloadDocument, 8, 13)); - ::CodeCompletionsExtractor extractor(completeResults.data()); + ::CodeCompletionsExtractor extractor( + functionOverloadDocument.translationUnit().cxTranslationUnit(), + completeResults.data()); ASSERT_THAT(extractor, HasCompletionChunks(Utf8String(), CodeCompletionChunks({ diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index 8b40ad1eb52..66d1e88c39c 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -315,7 +315,6 @@ std::ostream &operator<<(std::ostream &os, const CompletionsMessage &message) { os << "(" << message.codeCompletions << ", " - << completionCorrectionToText(message.neededCorrection) << ", " << message.ticketNumber << ")"; diff --git a/tests/unit/unittest/readandwritemessageblock-test.cpp b/tests/unit/unittest/readandwritemessageblock-test.cpp index bceeab7038e..4a02631e135 100644 --- a/tests/unit/unittest/readandwritemessageblock-test.cpp +++ b/tests/unit/unittest/readandwritemessageblock-test.cpp @@ -214,9 +214,7 @@ TEST_F(ReadAndWriteMessageBlock, CompareCompletionsMessage) { ClangBackEnd::CodeCompletions codeCompletions({Utf8StringLiteral("newFunction()")}); - CompareMessage(ClangBackEnd::CompletionsMessage(codeCompletions, - ClangBackEnd::CompletionCorrection::NoCorrection, - 1)); + CompareMessage(ClangBackEnd::CompletionsMessage(codeCompletions, 1)); } TEST_F(ReadAndWriteMessageBlock, CompareAnnotationsMessage) @@ -299,9 +297,7 @@ TEST_F(ReadAndWriteMessageBlock, ReadMessageAfterInterruption) ClangBackEnd::MessageEnvelop ReadAndWriteMessageBlock::writeCompletionsMessage() { ClangBackEnd::CompletionsMessage message( - ClangBackEnd::CodeCompletions({Utf8StringLiteral("newFunction()")}), - ClangBackEnd::CompletionCorrection::NoCorrection, - 1); + ClangBackEnd::CodeCompletions({Utf8StringLiteral("newFunction()")}), 1); writeMessageBlock.write(message);