From 039a34a369d96384cf72ae6979bff6f6fb36a0e7 Mon Sep 17 00:00:00 2001 From: Ivan Donchevskii Date: Wed, 17 Oct 2018 14:16:32 +0200 Subject: [PATCH] Clang: Adapt priorities for the same method/constructor overloads CXXMethod and CXXConstructor may have different priorities depending ony their origin and attributes. To keep them together in the sorted list we adapt their priorities to have the same value if their names match. To continue keeping ClassCompletion before ConstructorCompletion change the order of the completion kinds for the sort purposes. Change-Id: I36efe5d5dbaa77d604a54b1dafe07d67f44db4c9 Reviewed-by: Marco Bubke --- src/libs/clangsupport/codecompletion.h | 4 +- .../clangcompletionassistprocessor.cpp | 3 +- .../source/codecompletionsextractor.cpp | 47 ++++++++++--------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/libs/clangsupport/codecompletion.h b/src/libs/clangsupport/codecompletion.h index e3553f22a88..4a97fe08c15 100644 --- a/src/libs/clangsupport/codecompletion.h +++ b/src/libs/clangsupport/codecompletion.h @@ -42,16 +42,16 @@ using CodeCompletions = QVector; class CodeCompletion { public: - enum Kind : quint32 { + enum Kind : uint8_t { Other = 0, FunctionCompletionKind, FunctionDefinitionCompletionKind, FunctionOverloadCompletionKind, TemplateFunctionCompletionKind, + ClassCompletionKind, ConstructorCompletionKind, DestructorCompletionKind, VariableCompletionKind, - ClassCompletionKind, TypeAliasCompletionKind, TemplateClassCompletionKind, EnumerationCompletionKind, diff --git a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp index db68f680bc6..b16f458ca54 100644 --- a/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp +++ b/src/plugins/clangcodemodel/clangcompletionassistprocessor.cpp @@ -113,8 +113,7 @@ static bool isTheSameFunctionOverload(const CodeCompletion &completion, const QString &name, ClangAssistProposalItem *lastItem) { - return completion.hasParameters - && completion.completionKind == lastItem->firstCodeCompletion().completionKind + return completion.completionKind == lastItem->firstCodeCompletion().completionKind && lastItem->text() == name; } diff --git a/src/tools/clangbackend/source/codecompletionsextractor.cpp b/src/tools/clangbackend/source/codecompletionsextractor.cpp index 2e2817c72b7..f9c019b66d9 100644 --- a/src/tools/clangbackend/source/codecompletionsextractor.cpp +++ b/src/tools/clangbackend/source/codecompletionsextractor.cpp @@ -110,24 +110,30 @@ static CodeCompletions filterFunctionOverloads(const CodeCompletions &completion }); } -static ::Utils::optional classBeforeCXXConstructor(const CodeCompletion &first, - const CodeCompletion &second) +static void adaptOverloadsPriorities(CodeCompletions &codeCompletions) { - // Put ClassCompletionKind elements before ConstructorCompletionKind elements - // when they have the same name. - if (first.completionKind == CodeCompletion::ClassCompletionKind - && second.completionKind == CodeCompletion::ConstructorCompletionKind - && first.text == second.text) { - return true; - } + std::map> cachedOverloads; + for (CodeCompletion ¤tCompletion : codeCompletions) { + if (currentCompletion.completionKind != CodeCompletion::ConstructorCompletionKind + && currentCompletion.completionKind != CodeCompletion::FunctionCompletionKind) { + continue; + } - if (first.completionKind == CodeCompletion::ConstructorCompletionKind - && second.completionKind == CodeCompletion::ClassCompletionKind - && first.text == second.text) { - return false; + 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); + } } - - return ::Utils::optional(); } static void sortCodeCompletions(CodeCompletions &codeCompletions) @@ -138,14 +144,8 @@ static void sortCodeCompletions(CodeCompletions &codeCompletions) if (first.requiredFixIts.empty() != second.requiredFixIts.empty()) return first.requiredFixIts.empty() > second.requiredFixIts.empty(); - const ::Utils::optional classBeforeConstructorWithTheSameName - = classBeforeCXXConstructor(first, second); - if (classBeforeConstructorWithTheSameName) - return classBeforeConstructorWithTheSameName.value(); - - return (first.priority > 0 - && (first.priority < second.priority - || (first.priority == second.priority && first.text < second.text))); + return std::tie(first.priority, first.text, first.completionKind) + < std::tie(second.priority, second.text, second.completionKind); }; // Keep the order for the items with the same priority and name. @@ -164,6 +164,7 @@ void CodeCompletionsExtractor::handleCompletions(CodeCompletions &codeCompletion codeCompletions = overloadCompletions; } + adaptOverloadsPriorities(codeCompletions); sortCodeCompletions(codeCompletions); }