forked from qt-creator/qt-creator
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 <marco.bubke@qt.io>
This commit is contained in:
@@ -42,16 +42,16 @@ using CodeCompletions = QVector<CodeCompletion>;
|
|||||||
class CodeCompletion
|
class CodeCompletion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Kind : quint32 {
|
enum Kind : uint8_t {
|
||||||
Other = 0,
|
Other = 0,
|
||||||
FunctionCompletionKind,
|
FunctionCompletionKind,
|
||||||
FunctionDefinitionCompletionKind,
|
FunctionDefinitionCompletionKind,
|
||||||
FunctionOverloadCompletionKind,
|
FunctionOverloadCompletionKind,
|
||||||
TemplateFunctionCompletionKind,
|
TemplateFunctionCompletionKind,
|
||||||
|
ClassCompletionKind,
|
||||||
ConstructorCompletionKind,
|
ConstructorCompletionKind,
|
||||||
DestructorCompletionKind,
|
DestructorCompletionKind,
|
||||||
VariableCompletionKind,
|
VariableCompletionKind,
|
||||||
ClassCompletionKind,
|
|
||||||
TypeAliasCompletionKind,
|
TypeAliasCompletionKind,
|
||||||
TemplateClassCompletionKind,
|
TemplateClassCompletionKind,
|
||||||
EnumerationCompletionKind,
|
EnumerationCompletionKind,
|
||||||
|
@@ -113,8 +113,7 @@ static bool isTheSameFunctionOverload(const CodeCompletion &completion,
|
|||||||
const QString &name,
|
const QString &name,
|
||||||
ClangAssistProposalItem *lastItem)
|
ClangAssistProposalItem *lastItem)
|
||||||
{
|
{
|
||||||
return completion.hasParameters
|
return completion.completionKind == lastItem->firstCodeCompletion().completionKind
|
||||||
&& completion.completionKind == lastItem->firstCodeCompletion().completionKind
|
|
||||||
&& lastItem->text() == name;
|
&& lastItem->text() == name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -110,24 +110,30 @@ static CodeCompletions filterFunctionOverloads(const CodeCompletions &completion
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static ::Utils::optional<bool> classBeforeCXXConstructor(const CodeCompletion &first,
|
static void adaptOverloadsPriorities(CodeCompletions &codeCompletions)
|
||||||
const CodeCompletion &second)
|
|
||||||
{
|
{
|
||||||
// Put ClassCompletionKind elements before ConstructorCompletionKind elements
|
std::map<Utf8String, std::vector<CodeCompletion *>> cachedOverloads;
|
||||||
// when they have the same name.
|
for (CodeCompletion ¤tCompletion : codeCompletions) {
|
||||||
if (first.completionKind == CodeCompletion::ClassCompletionKind
|
if (currentCompletion.completionKind != CodeCompletion::ConstructorCompletionKind
|
||||||
&& second.completionKind == CodeCompletion::ConstructorCompletionKind
|
&& currentCompletion.completionKind != CodeCompletion::FunctionCompletionKind) {
|
||||||
&& first.text == second.text) {
|
continue;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first.completionKind == CodeCompletion::ConstructorCompletionKind
|
auto found = cachedOverloads.find(currentCompletion.text);
|
||||||
&& second.completionKind == CodeCompletion::ClassCompletionKind
|
if (found == cachedOverloads.end()) {
|
||||||
&& first.text == second.text) {
|
cachedOverloads[currentCompletion.text].push_back(¤tCompletion);
|
||||||
return false;
|
} 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<bool>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sortCodeCompletions(CodeCompletions &codeCompletions)
|
static void sortCodeCompletions(CodeCompletions &codeCompletions)
|
||||||
@@ -138,14 +144,8 @@ static void sortCodeCompletions(CodeCompletions &codeCompletions)
|
|||||||
if (first.requiredFixIts.empty() != second.requiredFixIts.empty())
|
if (first.requiredFixIts.empty() != second.requiredFixIts.empty())
|
||||||
return first.requiredFixIts.empty() > second.requiredFixIts.empty();
|
return first.requiredFixIts.empty() > second.requiredFixIts.empty();
|
||||||
|
|
||||||
const ::Utils::optional<bool> classBeforeConstructorWithTheSameName
|
return std::tie(first.priority, first.text, first.completionKind)
|
||||||
= classBeforeCXXConstructor(first, second);
|
< std::tie(second.priority, second.text, second.completionKind);
|
||||||
if (classBeforeConstructorWithTheSameName)
|
|
||||||
return classBeforeConstructorWithTheSameName.value();
|
|
||||||
|
|
||||||
return (first.priority > 0
|
|
||||||
&& (first.priority < second.priority
|
|
||||||
|| (first.priority == second.priority && first.text < second.text)));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Keep the order for the items with the same priority and name.
|
// Keep the order for the items with the same priority and name.
|
||||||
@@ -164,6 +164,7 @@ void CodeCompletionsExtractor::handleCompletions(CodeCompletions &codeCompletion
|
|||||||
codeCompletions = overloadCompletions;
|
codeCompletions = overloadCompletions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adaptOverloadsPriorities(codeCompletions);
|
||||||
sortCodeCompletions(codeCompletions);
|
sortCodeCompletions(codeCompletions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user