forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/13.0'
Conflicts: src/plugins/debugger/gdb/gdbsettings.cpp src/plugins/perfprofiler/perfprofilerruncontrol.cpp Change-Id: I0d5b914f9d9b5499920a5db484ef77af6ae748d5
This commit is contained in:
@@ -405,6 +405,7 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir, c
|
||||
setSupportedLanguage(langFilter);
|
||||
setActivateDocumentAutomatically(true);
|
||||
setCompletionAssistProvider(new ClangdCompletionAssistProvider(this));
|
||||
setFunctionHintAssistProvider(new ClangdFunctionHintProvider(this));
|
||||
setQuickFixAssistProvider(new ClangdQuickFixProvider(this));
|
||||
symbolSupport().setLimitRenamingToProjects(true);
|
||||
symbolSupport().setRenameResultsEnhancer([](const SearchResultItems &symbolOccurrencesInCode) {
|
||||
|
||||
@@ -102,13 +102,52 @@ private:
|
||||
QElapsedTimer m_timer;
|
||||
};
|
||||
|
||||
class ClangdFunctionHintProposalModel : public FunctionHintProposalModel
|
||||
{
|
||||
public:
|
||||
using FunctionHintProposalModel::FunctionHintProposalModel;
|
||||
|
||||
private:
|
||||
int activeArgument(const QString &prefix) const override
|
||||
{
|
||||
const int arg = activeArgumenForPrefix(prefix);
|
||||
if (arg < 0)
|
||||
return -1;
|
||||
m_currentArg = arg;
|
||||
return arg;
|
||||
}
|
||||
|
||||
QString text(int index) const override
|
||||
{
|
||||
using Parameters = QList<ParameterInformation>;
|
||||
if (index < 0 || m_sigis.signatures().size() <= index)
|
||||
return {};
|
||||
const SignatureInformation signature = m_sigis.signatures().at(index);
|
||||
QString label = signature.label();
|
||||
|
||||
const QList<QString> parameters = Utils::transform(signature.parameters().value_or(Parameters()),
|
||||
&ParameterInformation::label);
|
||||
if (parameters.size() <= m_currentArg)
|
||||
return label;
|
||||
|
||||
const QString ¶meterText = parameters.at(m_currentArg);
|
||||
const int start = label.indexOf(parameterText);
|
||||
const int end = start + parameterText.length();
|
||||
return label.mid(0, start).toHtmlEscaped() + "<b>" + parameterText.toHtmlEscaped() + "</b>"
|
||||
+ label.mid(end).toHtmlEscaped();
|
||||
}
|
||||
|
||||
mutable int m_currentArg = 0;
|
||||
};
|
||||
|
||||
class ClangdFunctionHintProcessor : public FunctionHintProcessor
|
||||
{
|
||||
public:
|
||||
ClangdFunctionHintProcessor(ClangdClient *client);
|
||||
ClangdFunctionHintProcessor(ClangdClient *client, int basePosition);
|
||||
|
||||
private:
|
||||
IAssistProposal *perform() override;
|
||||
IFunctionHintProposalModel *createModel(const SignatureHelp &signatureHelp) const override;
|
||||
|
||||
ClangdClient * const m_client;
|
||||
};
|
||||
@@ -138,7 +177,8 @@ IAssistProcessor *ClangdCompletionAssistProvider::createProcessor(
|
||||
switch (contextAnalyzer.completionAction()) {
|
||||
case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen:
|
||||
qCDebug(clangdLogCompletion) << "creating function hint processor";
|
||||
return new ClangdFunctionHintProcessor(m_client);
|
||||
return new ClangdFunctionHintProcessor(m_client,
|
||||
contextAnalyzer.positionForProposal());
|
||||
case ClangCompletionContextAnalyzer::CompletePreprocessorDirective:
|
||||
qCDebug(clangdLogCompletion) << "creating macro processor";
|
||||
return new CustomAssistProcessor(m_client,
|
||||
@@ -606,8 +646,8 @@ QList<AssistProposalItemInterface *> ClangdCompletionAssistProcessor::generateCo
|
||||
return itemGenerator(items);
|
||||
}
|
||||
|
||||
ClangdFunctionHintProcessor::ClangdFunctionHintProcessor(ClangdClient *client)
|
||||
: FunctionHintProcessor(client)
|
||||
ClangdFunctionHintProcessor::ClangdFunctionHintProcessor(ClangdClient *client, int basePosition)
|
||||
: FunctionHintProcessor(client, basePosition)
|
||||
, m_client(client)
|
||||
{}
|
||||
|
||||
@@ -621,6 +661,12 @@ IAssistProposal *ClangdFunctionHintProcessor::perform()
|
||||
return FunctionHintProcessor::perform();
|
||||
}
|
||||
|
||||
IFunctionHintProposalModel *ClangdFunctionHintProcessor::createModel(
|
||||
const SignatureHelp &signatureHelp) const
|
||||
{
|
||||
return new ClangdFunctionHintProposalModel(signatureHelp);
|
||||
}
|
||||
|
||||
ClangdCompletionCapabilities::ClangdCompletionCapabilities(const JsonObject &object)
|
||||
: TextDocumentClientCapabilities::CompletionCapabilities(object)
|
||||
{
|
||||
@@ -631,4 +677,18 @@ ClangdCompletionCapabilities::ClangdCompletionCapabilities(const JsonObject &obj
|
||||
}
|
||||
}
|
||||
|
||||
ClangdFunctionHintProvider::ClangdFunctionHintProvider(ClangdClient *client)
|
||||
: FunctionHintAssistProvider(client)
|
||||
, m_client(client)
|
||||
{}
|
||||
|
||||
IAssistProcessor *ClangdFunctionHintProvider::createProcessor(
|
||||
const AssistInterface *interface) const
|
||||
{
|
||||
ClangCompletionContextAnalyzer contextAnalyzer(interface->textDocument(),
|
||||
interface->position(), false, {});
|
||||
contextAnalyzer.analyze();
|
||||
return new ClangdFunctionHintProcessor(m_client, contextAnalyzer.positionForProposal());
|
||||
}
|
||||
|
||||
} // namespace ClangCodeModel::Internal
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
|
||||
#include <languageclient/languageclientcompletionassist.h>
|
||||
// Copyright (C) 2022 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <languageclient/languageclientcompletionassist.h>
|
||||
#include <languageclient/languageclientfunctionhint.h>
|
||||
#include <languageserverprotocol/clientcapabilities.h>
|
||||
|
||||
namespace TextEditor { class IAssistProcessor; }
|
||||
@@ -37,4 +36,16 @@ public:
|
||||
explicit ClangdCompletionCapabilities(const JsonObject &object);
|
||||
};
|
||||
|
||||
class ClangdFunctionHintProvider : public LanguageClient::FunctionHintAssistProvider
|
||||
{
|
||||
public:
|
||||
ClangdFunctionHintProvider(ClangdClient *client);
|
||||
|
||||
private:
|
||||
TextEditor::IAssistProcessor *createProcessor(
|
||||
const TextEditor::AssistInterface *assistInterface) const override;
|
||||
|
||||
ClangdClient * const m_client;
|
||||
};
|
||||
|
||||
} // namespace ClangCodeModel::Internal
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <texteditor/blockrange.h>
|
||||
#include <texteditor/codeassist/assistproposaliteminterface.h>
|
||||
#include <texteditor/codeassist/genericproposal.h>
|
||||
#include <texteditor/codeassist/ifunctionhintproposalmodel.h>
|
||||
#include <texteditor/codeassist/textdocumentmanipulatorinterface.h>
|
||||
#include <texteditor/semantichighlighter.h>
|
||||
#include <texteditor/textmark.h>
|
||||
@@ -1832,12 +1833,12 @@ void ClangdTestCompletion::testFunctionHints()
|
||||
|
||||
QVERIFY(proposal);
|
||||
QVERIFY(hasItem(proposal, "f() -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(int a) -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(const QString &s) -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(char c, int optional = 3) -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(char c, int optional1 = 3, int optional2 = 3) -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(const TType<QString> *t) -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(bool) -> TType<QString>"));
|
||||
QVERIFY(hasItem(proposal, "f(<b>int a</b>) -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(<b>const QString &s</b>) -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(<b>char c</b>, int optional = 3) -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(<b>char c</b>, int optional1 = 3, int optional2 = 3) -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(<b>const TType<QString> *t</b>) -> void"));
|
||||
QVERIFY(hasItem(proposal, "f(<b>bool</b>) -> TType<QString>"));
|
||||
}
|
||||
|
||||
void ClangdTestCompletion::testFunctionHintsFiltered()
|
||||
@@ -1855,7 +1856,6 @@ void ClangdTestCompletion::testFunctionHintsFiltered()
|
||||
QVERIFY(proposal);
|
||||
QCOMPARE(proposal->size(), 2);
|
||||
QVERIFY(hasItem(proposal, "func(const S &s, <b>int j</b>) -> void"));
|
||||
QEXPECT_FAIL("", "QTCREATORBUG-26346", Abort);
|
||||
QVERIFY(hasItem(proposal, "func(const S &s, <b>int j</b>, int k) -> void"));
|
||||
}
|
||||
|
||||
@@ -1868,7 +1868,6 @@ void ClangdTestCompletion::testFunctionHintConstructor()
|
||||
QVERIFY(!hasItem(proposal, "globalVariable"));
|
||||
QVERIFY(!hasItem(proposal, " class"));
|
||||
QVERIFY(hasItem(proposal, "Foo(<b>int</b>)"));
|
||||
QEXPECT_FAIL("", "QTCREATORBUG-26346", Abort);
|
||||
QVERIFY(hasItem(proposal, "Foo(<b>int</b>, double)"));
|
||||
}
|
||||
|
||||
@@ -2066,7 +2065,8 @@ void ClangdTestCompletion::getProposal(const QString &fileName,
|
||||
{
|
||||
const TextDocument * const doc = document(fileName);
|
||||
QVERIFY(doc);
|
||||
const int pos = doc->document()->toPlainText().indexOf(" /* COMPLETE HERE */");
|
||||
const QString docContent = doc->document()->toPlainText();
|
||||
const int pos = docContent.indexOf(" /* COMPLETE HERE */");
|
||||
QVERIFY(pos != -1);
|
||||
if (cursorPos)
|
||||
*cursorPos = pos;
|
||||
@@ -2110,6 +2110,13 @@ void ClangdTestCompletion::getProposal(const QString &fileName,
|
||||
QVERIFY(timer.isActive());
|
||||
QVERIFY(proposal);
|
||||
proposalModel = proposal->model();
|
||||
if (auto functionHintModel = proposalModel.dynamicCast<IFunctionHintProposalModel>()) {
|
||||
const int proposalBasePos = proposal->basePosition();
|
||||
// The language client function hint model expects that activeArgument was called before the
|
||||
// text of individual hints is accessed. This is usually done by the proposal widget. But
|
||||
// since we don't have a proposal widget in this test, we have to call it manually.
|
||||
functionHintModel->activeArgument(docContent.mid(proposalBasePos, pos - proposalBasePos));
|
||||
}
|
||||
delete proposal;
|
||||
|
||||
// The "dot" test files are only used once.
|
||||
|
||||
Reference in New Issue
Block a user