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::FunctionCompletionKind
|| ccr.completionKind == CodeCompletion::FunctionDefinitionCompletionKind || ccr.completionKind == CodeCompletion::FunctionDefinitionCompletionKind
|| ccr.completionKind == CodeCompletion::DestructorCompletionKind || ccr.completionKind == CodeCompletion::DestructorCompletionKind
|| ccr.completionKind == CodeCompletion::ConstructorCompletionKind
|| ccr.completionKind == CodeCompletion::SignalCompletionKind || ccr.completionKind == CodeCompletion::SignalCompletionKind
|| ccr.completionKind == CodeCompletion::SlotCompletionKind)) { || ccr.completionKind == CodeCompletion::SlotCompletionKind)) {
// When the user typed the opening parenthesis, he'll likely also type the closing one, // 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); return m_codeCompletions.at(0);
} }
void ClangAssistProposalItem::removeFirstCodeCompletion()
{
QTC_ASSERT(!m_codeCompletions.empty(), return;);
m_codeCompletions.erase(m_codeCompletions.begin());
}
} // namespace Internal } // namespace Internal
} // namespace ClangCodeModel } // namespace ClangCodeModel

View File

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

View File

@@ -77,16 +77,23 @@ static void addAssistProposalItem(QList<AssistProposalItemInterface *> &items,
} }
static void addFunctionOverloadAssistProposalItem(QList<AssistProposalItemInterface *> &items, static void addFunctionOverloadAssistProposalItem(QList<AssistProposalItemInterface *> &items,
AssistProposalItemInterface *sameItem,
const ClangCompletionAssistInterface *interface, const ClangCompletionAssistInterface *interface,
const CodeCompletion &codeCompletion, const CodeCompletion &codeCompletion,
const QString &name) const QString &name)
{ {
ClangBackEnd::CodeCompletionChunk resultType = codeCompletion.chunks.first(); ClangBackEnd::CodeCompletionChunk resultType = codeCompletion.chunks.first();
QTC_ASSERT(resultType.kind == ClangBackEnd::CodeCompletionChunk::ResultType, auto *item = static_cast<ClangAssistProposalItem *>(sameItem);
return;);
auto *item = static_cast<ClangAssistProposalItem *>(items.last());
item->setHasOverloadsWithParameters(true); 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(); QTextCursor cursor = interface->textEditorWidget()->textCursor();
cursor.setPosition(interface->position()); cursor.setPosition(interface->position());
cursor.movePosition(QTextCursor::StartOfWord); cursor.movePosition(QTextCursor::StartOfWord);
@@ -121,10 +128,33 @@ static QList<AssistProposalItemInterface *> toAssistProposalItems(
? CompletionChunksToTextConverter::convertToName(codeCompletion.chunks) ? CompletionChunksToTextConverter::convertToName(codeCompletion.chunks)
: codeCompletion.text.toString(); : codeCompletion.text.toString();
if (!items.empty() && items.last()->text() == name && codeCompletion.hasParameters) if (codeCompletion.completionKind == CodeCompletion::ConstructorCompletionKind
addFunctionOverloadAssistProposalItem(items, interface, codeCompletion, name); || codeCompletion.completionKind == CodeCompletion::ClassCompletionKind) {
else 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); 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; return items;