Clang: Better handle constructor overloads

Follow up for 0f96f735f0. Constructors have worse support
in Clang for their definitions but have proper overloads
for the references.

Change-Id: Ie002ae74b0d15f0fe00126042a7f61172b82946b
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
Ivan Donchevskii
2018-08-02 15:15:59 +02:00
parent 0ec471971b
commit 843f31ae04
3 changed files with 48 additions and 10 deletions

View File

@@ -183,6 +183,7 @@ void ClangAssistProposalItem::apply(TextEditor::TextDocumentManipulatorInterface
(ccr.completionKind == CodeCompletion::FunctionCompletionKind
|| ccr.completionKind == CodeCompletion::FunctionDefinitionCompletionKind
|| ccr.completionKind == CodeCompletion::DestructorCompletionKind
|| ccr.completionKind == CodeCompletion::ConstructorCompletionKind
|| ccr.completionKind == CodeCompletion::SignalCompletionKind
|| ccr.completionKind == CodeCompletion::SlotCompletionKind)) {
// When the user typed the opening parenthesis, he'll likely also type the closing one,
@@ -476,5 +477,11 @@ const ClangBackEnd::CodeCompletion &ClangAssistProposalItem::firstCodeCompletion
return m_codeCompletions.at(0);
}
void ClangAssistProposalItem::removeFirstCodeCompletion()
{
QTC_ASSERT(!m_codeCompletions.empty(), return;);
m_codeCompletions.erase(m_codeCompletions.begin());
}
} // namespace Internal
} // namespace ClangCodeModel

View File

@@ -59,6 +59,7 @@ public:
void appendCodeCompletion(const ClangBackEnd::CodeCompletion &firstCodeCompletion);
const ClangBackEnd::CodeCompletion &firstCodeCompletion() const;
void removeFirstCodeCompletion();
private:
const QVector<ClangBackEnd::FixItContainer> &firstCompletionFixIts() const;

View File

@@ -77,16 +77,23 @@ static void addAssistProposalItem(QList<AssistProposalItemInterface *> &items,
}
static void addFunctionOverloadAssistProposalItem(QList<AssistProposalItemInterface *> &items,
const ClangCompletionAssistInterface *interface,
const CodeCompletion &codeCompletion,
const QString &name)
AssistProposalItemInterface *sameItem,
const ClangCompletionAssistInterface *interface,
const CodeCompletion &codeCompletion,
const QString &name)
{
ClangBackEnd::CodeCompletionChunk resultType = codeCompletion.chunks.first();
QTC_ASSERT(resultType.kind == ClangBackEnd::CodeCompletionChunk::ResultType,
return;);
auto *item = static_cast<ClangAssistProposalItem *>(items.last());
auto *item = static_cast<ClangAssistProposalItem *>(sameItem);
item->setHasOverloadsWithParameters(true);
if (resultType.kind != ClangBackEnd::CodeCompletionChunk::ResultType) {
// It's the constructor.
// CLANG-UPGRADE-CHECK: Can we get here with constructor definition?
if (!item->firstCodeCompletion().hasParameters)
item->removeFirstCodeCompletion();
item->appendCodeCompletion(codeCompletion);
return;
}
QTextCursor cursor = interface->textEditorWidget()->textCursor();
cursor.setPosition(interface->position());
cursor.movePosition(QTextCursor::StartOfWord);
@@ -121,10 +128,33 @@ static QList<AssistProposalItemInterface *> toAssistProposalItems(
? CompletionChunksToTextConverter::convertToName(codeCompletion.chunks)
: codeCompletion.text.toString();
if (!items.empty() && items.last()->text() == name && codeCompletion.hasParameters)
addFunctionOverloadAssistProposalItem(items, interface, codeCompletion, name);
else
if (codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind
|| codeCompletion.completionKind == CodeCompletion::ClassCompletionKind) {
auto samePreviousConstructor
= std::find_if(items.begin(),
items.end(),
[&name](const AssistProposalItemInterface *item) {
return item->text() == name;
});
if (samePreviousConstructor == items.end()) {
addAssistProposalItem(items, codeCompletion, name);
} else {
addFunctionOverloadAssistProposalItem(items, *samePreviousConstructor, interface,
codeCompletion, name);
}
continue;
}
if (!items.empty() && items.last()->text() == name) {
if ((codeCompletion.completionKind == CodeCompletion::FunctionCompletionKind
|| codeCompletion.completionKind == CodeCompletion::FunctionDefinitionCompletionKind)
&& codeCompletion.hasParameters) {
addFunctionOverloadAssistProposalItem(items, items.back(), interface,
codeCompletion, name);
}
} else {
addAssistProposalItem(items, codeCompletion, name);
}
}
return items;