Commit 55fa5584 authored by Sergey Kalinichev's avatar Sergey Kalinichev

Try harder not to add unrelated completion items to the best matches group

This also takes typedef's, templates, functions and references into consideration
parent 2860cb17
......@@ -27,6 +27,7 @@
#include <language/duchain/declaration.h>
#include <language/duchain/duchainutils.h>
#include <language/duchain/types/functiontype.h>
#include <language/duchain/types/typealiastype.h>
#include <language/interfaces/iastcontainer.h>
#include <language/codecompletion/codecompletionitem.h>
#include <language/codecompletion/codecompletionmodel.h>
......@@ -352,26 +353,43 @@ int codeCompletionPriorityToMatchQuality(unsigned int completionPriority)
return 10u - qBound(0u, completionPriority, 80u) / 8;
}
/// Adjusts piority for the @p decl
int adjustPriorityForDeclaration(Declaration* decl, unsigned int completionPriority)
int adjustPriorityForType(const AbstractType::Ptr& type, int completionPriority)
{
if (completionPriority == CCP_LocalDeclarationSimiliar) {
const auto type = decl->abstractType();
if (type) {
const auto whichType = type->whichType();
if (whichType == AbstractType::TypePointer) {
// Clang considers all pointers as similar, this is not what we want.
completionPriority += 4;
} else if (whichType == AbstractType::TypeStructure) {
// Clang considers all classes as similar too...
completionPriority += 4;
}
const auto modifier = 4;
if (type) {
const auto whichType = type->whichType();
if (whichType == AbstractType::TypePointer || whichType == AbstractType::TypeReference) {
// Clang considers all pointers as similar, this is not what we want.
completionPriority += modifier;
} else if (whichType == AbstractType::TypeStructure) {
// Clang considers all classes as similar too...
completionPriority += modifier;
} else if (whichType == AbstractType::TypeDelayed) {
completionPriority += modifier;
} else if (whichType == AbstractType::TypeAlias) {
auto aliasedType = type.cast<TypeAliasType>();
return adjustPriorityForType(aliasedType ? aliasedType->type() : AbstractType::Ptr(), completionPriority);
} else if (whichType == AbstractType::TypeFunction) {
auto functionType = type.cast<FunctionType>();
return adjustPriorityForType(functionType ? functionType->returnType() : AbstractType::Ptr(), completionPriority);
}
} else {
completionPriority += modifier;
}
return completionPriority;
}
/// Adjusts priority for the @p decl
int adjustPriorityForDeclaration(Declaration* decl, unsigned int completionPriority)
{
if(completionPriority < CCP_LocalDeclarationSimiliar || completionPriority > CCP_SuperCompletion){
return completionPriority;
}
return adjustPriorityForType(decl->abstractType(), completionPriority);
}
/**
* @return Whether the declaration represented by identifier @p identifier qualifies as completion result
*
......
......@@ -689,4 +689,24 @@ void TestCodeCompletion::testCompletionPriority_data()
QTest::newRow("primary-types")
<< "class A{}; int main(){A a; int b; bool c = \n "
<< CompletionPriorityItems{{1,0}, {{"a", 0, 34}, {"b", 8, 0}, {"c", 9, 0}}};
QTest::newRow("reference")
<< "class A{}; class B{}; class C : public B{};"
"int main(){A tmp; A& a = tmp; C tmp2; C& c = tmp2; B& b =\n ;}"
<< CompletionPriorityItems{{1,0}, {{"a", 0, 21}, {"b", 9, 0},
{"c", 8, 0, QStringLiteral("Reference to derived class is not added to the Best Matches group")}}};
QTest::newRow("typedef")
<< "struct A{}; struct B{}; typedef A AA; typedef B BB; void f(A p);"
"int main(){ BB b; AA a; f(\n }"
<< CompletionPriorityItems{{1,0}, {{"a", 9, 0}, {"b", 0, 21}}};
QTest::newRow("returnType")
<< "struct A{}; struct B{}; struct Test{A f();B g(); Test() { A a =\n }};"
<< CompletionPriorityItems{{1,0}, {{"f", 9, 0}, {"g", 0, 21}}};
QTest::newRow("template")
<< "template <typename T> class Class{}; template <typename T> class Class2{};"
"int main(){ Class<int> a; Class2<int> b =\n }"
<< CompletionPriorityItems{{1,0}, {{"b", 9, 0}, {"a", 0, 21}}};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment