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 @@ ...@@ -27,6 +27,7 @@
#include <language/duchain/declaration.h> #include <language/duchain/declaration.h>
#include <language/duchain/duchainutils.h> #include <language/duchain/duchainutils.h>
#include <language/duchain/types/functiontype.h> #include <language/duchain/types/functiontype.h>
#include <language/duchain/types/typealiastype.h>
#include <language/interfaces/iastcontainer.h> #include <language/interfaces/iastcontainer.h>
#include <language/codecompletion/codecompletionitem.h> #include <language/codecompletion/codecompletionitem.h>
#include <language/codecompletion/codecompletionmodel.h> #include <language/codecompletion/codecompletionmodel.h>
...@@ -352,26 +353,43 @@ int codeCompletionPriorityToMatchQuality(unsigned int completionPriority) ...@@ -352,26 +353,43 @@ int codeCompletionPriorityToMatchQuality(unsigned int completionPriority)
return 10u - qBound(0u, completionPriority, 80u) / 8; return 10u - qBound(0u, completionPriority, 80u) / 8;
} }
/// Adjusts piority for the @p decl int adjustPriorityForType(const AbstractType::Ptr& type, int completionPriority)
int adjustPriorityForDeclaration(Declaration* decl, unsigned int completionPriority)
{ {
if (completionPriority == CCP_LocalDeclarationSimiliar) { const auto modifier = 4;
const auto type = decl->abstractType(); if (type) {
if (type) { const auto whichType = type->whichType();
const auto whichType = type->whichType(); if (whichType == AbstractType::TypePointer || whichType == AbstractType::TypeReference) {
if (whichType == AbstractType::TypePointer) { // Clang considers all pointers as similar, this is not what we want.
// Clang considers all pointers as similar, this is not what we want. completionPriority += modifier;
completionPriority += 4; } else if (whichType == AbstractType::TypeStructure) {
} else if (whichType == AbstractType::TypeStructure) { // Clang considers all classes as similar too...
// Clang considers all classes as similar too... completionPriority += modifier;
completionPriority += 4; } 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; 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 * @return Whether the declaration represented by identifier @p identifier qualifies as completion result
* *
......
...@@ -689,4 +689,24 @@ void TestCodeCompletion::testCompletionPriority_data() ...@@ -689,4 +689,24 @@ void TestCodeCompletion::testCompletionPriority_data()
QTest::newRow("primary-types") QTest::newRow("primary-types")
<< "class A{}; int main(){A a; int b; bool c = \n " << "class A{}; int main(){A a; int b; bool c = \n "
<< CompletionPriorityItems{{1,0}, {{"a", 0, 34}, {"b", 8, 0}, {"c", 9, 0}}}; << 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