From 810896936b83ec9addb2a080e3e9ee0308386cf2 Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Tue, 31 Jul 2018 09:48:02 +0200 Subject: [PATCH] Clang: Improve function definition completion Insert argument list together with completion. Task-number: QTCREATORBUG-20826 Change-Id: I4aa9faaa04bcd3ca014306aad27843c2b4419d3c Reviewed-by: Marco Bubke --- src/libs/clangsupport/codecompletion.h | 1 + .../clangassistproposalitem.cpp | 27 ++++++++++++++++++- .../source/clangcodecompleteresults.cpp | 12 --------- .../source/clangcodecompleteresults.h | 2 -- .../source/codecompletionsextractor.cpp | 9 ++++++- 5 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/libs/clangsupport/codecompletion.h b/src/libs/clangsupport/codecompletion.h index fdb637560c3..e3553f22a88 100644 --- a/src/libs/clangsupport/codecompletion.h +++ b/src/libs/clangsupport/codecompletion.h @@ -45,6 +45,7 @@ public: enum Kind : quint32 { Other = 0, FunctionCompletionKind, + FunctionDefinitionCompletionKind, FunctionOverloadCompletionKind, TemplateFunctionCompletionKind, ConstructorCompletionKind, diff --git a/src/plugins/clangcodemodel/clangassistproposalitem.cpp b/src/plugins/clangcodemodel/clangassistproposalitem.cpp index 301ce193723..1729de37361 100644 --- a/src/plugins/clangcodemodel/clangassistproposalitem.cpp +++ b/src/plugins/clangcodemodel/clangassistproposalitem.cpp @@ -164,6 +164,7 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface if (autoInsertBrackets && (ccr.completionKind == CodeCompletion::FunctionCompletionKind + || ccr.completionKind == CodeCompletion::FunctionDefinitionCompletionKind || ccr.completionKind == CodeCompletion::DestructorCompletionKind || ccr.completionKind == CodeCompletion::SignalCompletionKind || ccr.completionKind == CodeCompletion::SlotCompletionKind)) { @@ -176,17 +177,40 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface while (manipulator.characterAt(cursor.position()) == ':') cursor.movePosition(QTextCursor::PreviousWord, QTextCursor::MoveAnchor, 2); + const int previousWordStart = cursor.position(); // Move to the last character in the previous word cursor.movePosition(QTextCursor::NextWord); moveToPrevChar(manipulator, cursor); + const QString previousWord = manipulator.textAt(previousWordStart, + cursor.position() - previousWordStart + 1); + bool abandonParen = false; - if (manipulator.characterAt(cursor.position()) == '&') { + if (previousWord == "&") { moveToPrevChar(manipulator, cursor); const QChar prevChar = manipulator.characterAt(cursor.position()); abandonParen = QString("(;,{}").contains(prevChar); } if (!abandonParen) abandonParen = isAtUsingDeclaration(manipulator, basePosition); + if (!abandonParen && ccr.completionKind == CodeCompletion::FunctionDefinitionCompletionKind) { + const CodeCompletionChunk resultType = ccr.chunks.first(); + QTC_ASSERT(resultType.kind == CodeCompletionChunk::ResultType, return;); + if (previousWord == resultType.text.toString()) { + bool skipChunks = true; + for (const CodeCompletionChunk &chunk : ccr.chunks) { + if (chunk.kind == CodeCompletionChunk::TypedText) { + skipChunks = false; + continue; + } + if (skipChunks) + continue; + extraCharacters += chunk.text; + } + + // To skip the next block. + abandonParen = true; + } + } if (!abandonParen) { if (completionSettings.m_spaceAfterFunctionName) extraCharacters += QLatin1Char(' '); @@ -338,6 +362,7 @@ QIcon ClangAssistProposalItem::icon() const case CodeCompletion::ConstructorCompletionKind: case CodeCompletion::DestructorCompletionKind: case CodeCompletion::FunctionCompletionKind: + case CodeCompletion::FunctionDefinitionCompletionKind: case CodeCompletion::TemplateFunctionCompletionKind: case CodeCompletion::ObjCMessageCompletionKind: switch (m_codeCompletion.availability) { diff --git a/src/tools/clangbackend/source/clangcodecompleteresults.cpp b/src/tools/clangbackend/source/clangcodecompleteresults.cpp index af80d739bfc..818aa9360e3 100644 --- a/src/tools/clangbackend/source/clangcodecompleteresults.cpp +++ b/src/tools/clangbackend/source/clangcodecompleteresults.cpp @@ -56,24 +56,12 @@ bool ClangCodeCompleteResults::hasResults() const return !isNull() && !isEmpty(); } -bool ClangCodeCompleteResults::hasNoResultsForDotCompletion() const -{ - return !hasResults() && isDotCompletion(); -} - bool ClangCodeCompleteResults::hasUnknownContext() const { const unsigned long long contexts = clang_codeCompleteGetContexts(cxCodeCompleteResults); return contexts == CXCompletionContext_Unknown; } -bool ClangCodeCompleteResults::isDotCompletion() const -{ - const unsigned long long contexts = clang_codeCompleteGetContexts(cxCodeCompleteResults); - - return contexts & CXCompletionContext_DotMemberAccess; -} - CXCodeCompleteResults *ClangCodeCompleteResults::data() const { return cxCodeCompleteResults; diff --git a/src/tools/clangbackend/source/clangcodecompleteresults.h b/src/tools/clangbackend/source/clangcodecompleteresults.h index 0b1ae11df8e..000c424b33b 100644 --- a/src/tools/clangbackend/source/clangcodecompleteresults.h +++ b/src/tools/clangbackend/source/clangcodecompleteresults.h @@ -49,10 +49,8 @@ public: bool isEmpty() const; bool hasResults() const; - bool hasNoResultsForDotCompletion() const; bool hasUnknownContext() const; - bool isDotCompletion() const; CXCodeCompleteResults *data() const; diff --git a/src/tools/clangbackend/source/codecompletionsextractor.cpp b/src/tools/clangbackend/source/codecompletionsextractor.cpp index 014116102c4..bd961dc4aa5 100644 --- a/src/tools/clangbackend/source/codecompletionsextractor.cpp +++ b/src/tools/clangbackend/source/codecompletionsextractor.cpp @@ -176,6 +176,9 @@ void CodeCompletionsExtractor::extractText() 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) { @@ -192,7 +195,11 @@ void CodeCompletionsExtractor::extractMethodCompletionKind() } } - currentCodeCompletion_.completionKind = CodeCompletion::FunctionCompletionKind; + currentCodeCompletion_.completionKind = CodeCompletion::FunctionDefinitionCompletionKind; + if ((contexts & CXCompletionContext_DotMemberAccess) + || (contexts & CXCompletionContext_ArrowMemberAccess)) { + currentCodeCompletion_.completionKind = CodeCompletion::FunctionCompletionKind; + } } void CodeCompletionsExtractor::extractMacroCompletionKind()