LSP: Support remote LSP file paths

Change-Id: If3cf1b8d675ef091427dbcd703c7d14b384a1b3a
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
David Schulz
2022-12-15 07:23:55 +01:00
parent 0b33a08af1
commit 2d0456f085
36 changed files with 424 additions and 310 deletions

View File

@@ -387,7 +387,7 @@ MessageId requestAst(Client *client, const FilePath &filePath, const Range range
explicit AstRequest(const AstParams &params) : Request("textDocument/ast", params) {}
};
AstRequest request(AstParams(TextDocumentIdentifier(DocumentUri::fromFilePath(filePath)),
AstRequest request(AstParams(TextDocumentIdentifier(client->hostPathToServerUri(filePath)),
range));
request.setResponseCallback([handler, reqId = request.id()](AstRequest::Response response) {
const auto result = response.result();

View File

@@ -274,7 +274,7 @@ public:
QTextCursor adjustedCursor(const QTextCursor &cursor, const TextDocument *doc);
void setHelpItemForTooltip(const MessageId &token,
const DocumentUri &uri,
const Utils::FilePath &filePath,
const QString &fqn = {},
HelpItem::Category category = HelpItem::Unknown,
const QString &type = {});
@@ -409,8 +409,8 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
d->handleSemanticTokens(doc, tokens, version, force);
});
hoverHandler()->setHelpItemProvider([this](const HoverRequest::Response &response,
const DocumentUri &uri) {
gatherHelpItemForTooltip(response, uri);
const Utils::FilePath &filePath) {
gatherHelpItemForTooltip(response, filePath);
});
connect(this, &Client::workDone, this,
@@ -462,7 +462,7 @@ void ClangdClient::openExtraFile(const Utils::FilePath &filePath, const QString
return;
TextDocumentItem item;
item.setLanguageId("cpp");
item.setUri(DocumentUri::fromFilePath(filePath));
item.setUri(hostPathToServerUri(filePath));
item.setText(!content.isEmpty() ? content : QString::fromUtf8(cxxFile.readAll()));
item.setVersion(0);
sendMessage(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)),
@@ -480,7 +480,7 @@ void ClangdClient::closeExtraFile(const Utils::FilePath &filePath)
return;
d->openedExtraFiles.erase(it);
sendMessage(DidCloseTextDocumentNotification(DidCloseTextDocumentParams(
TextDocumentIdentifier{DocumentUri::fromFilePath(filePath)})),
TextDocumentIdentifier{hostPathToServerUri(filePath)})),
SendDocUpdates::Ignore);
}
@@ -533,7 +533,7 @@ void ClangdClient::handleDiagnostics(const PublishDiagnosticsParams &params)
{
const DocumentUri &uri = params.uri();
Client::handleDiagnostics(params);
const int docVersion = documentVersion(uri.toFilePath());
const int docVersion = documentVersion(uri);
if (params.version().value_or(docVersion) != docVersion)
return;
for (const Diagnostic &diagnostic : params.diagnostics()) {
@@ -593,11 +593,10 @@ class ClangdDiagnosticManager : public LanguageClient::DiagnosticManager
return doc && doc->filePath() == filePath;
}
void showDiagnostics(const DocumentUri &uri, int version) override
void showDiagnostics(const Utils::FilePath &filePath, int version) override
{
const Utils::FilePath filePath = uri.toFilePath();
getClient()->clearTasks(filePath);
DiagnosticManager::showDiagnostics(uri, version);
DiagnosticManager::showDiagnostics(filePath, version);
if (isCurrentDocument(filePath))
getClient()->switchIssuePaneEntries(filePath);
}
@@ -851,7 +850,7 @@ MessageId ClangdClient::getAndHandleAst(const TextDocOrFile &doc, const AstHandl
MessageId ClangdClient::requestSymbolInfo(const Utils::FilePath &filePath, const Position &position,
const SymbolInfoHandler &handler)
{
const TextDocumentIdentifier docId(DocumentUri::fromFilePath(filePath));
const TextDocumentIdentifier docId(hostPathToServerUri(filePath));
const TextDocumentPositionParams params(docId, position);
SymbolInfoRequest symReq(params);
symReq.setResponseCallback([handler, reqId = symReq.id()]
@@ -932,15 +931,16 @@ void ClangdClient::switchHeaderSource(const Utils::FilePath &filePath, bool inNe
{
public:
using Request::Request;
explicit SwitchSourceHeaderRequest(const Utils::FilePath &filePath)
: Request("textDocument/switchSourceHeader",
TextDocumentIdentifier(DocumentUri::fromFilePath(filePath))) {}
explicit SwitchSourceHeaderRequest(const DocumentUri &uri)
: Request("textDocument/switchSourceHeader", TextDocumentIdentifier(uri))
{}
};
SwitchSourceHeaderRequest req(filePath);
req.setResponseCallback([inNextSplit](const SwitchSourceHeaderRequest::Response &response) {
SwitchSourceHeaderRequest req(hostPathToServerUri(filePath));
req.setResponseCallback([inNextSplit, pathMapper = hostPathMapper()](
const SwitchSourceHeaderRequest::Response &response) {
if (const std::optional<QJsonValue> result = response.result()) {
const DocumentUri uri = DocumentUri::fromProtocol(result->toString());
const Utils::FilePath filePath = uri.toFilePath();
const Utils::FilePath filePath = uri.toFilePath(pathMapper);
if (!filePath.isEmpty())
CppEditor::openEditor(filePath, inNextSplit);
}
@@ -976,7 +976,7 @@ void ClangdClient::findLocalUsages(TextDocument *document, const QTextCursor &cu
}
void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverResponse,
const DocumentUri &uri)
const Utils::FilePath &filePath)
{
if (const std::optional<HoverResult> result = hoverResponse.result()) {
if (auto hover = std::get_if<Hover>(&(*result))) {
@@ -994,7 +994,7 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
const QString macroName = markupString.mid(nameStart,
closingQuoteIndex - nameStart);
d->setHelpItemForTooltip(hoverResponse.id(),
uri,
filePath,
macroName,
HelpItem::Macro);
return;
@@ -1006,11 +1006,12 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
cleanString.remove('`');
const QStringList lines = cleanString.trimmed().split('\n');
if (!lines.isEmpty()) {
const auto filePath = Utils::FilePath::fromUserInput(lines.last().simplified());
if (filePath.exists()) {
const auto markupFilePath = Utils::FilePath::fromUserInput(
lines.last().simplified());
if (markupFilePath.exists()) {
d->setHelpItemForTooltip(hoverResponse.id(),
uri,
filePath.fileName(),
filePath,
markupFilePath.fileName(),
HelpItem::Brief);
return;
}
@@ -1019,9 +1020,10 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
}
}
const TextDocument * const doc = documentForFilePath(uri.toFilePath());
const TextDocument * const doc = documentForFilePath(filePath);
QTC_ASSERT(doc, return);
const auto astHandler = [this, uri, hoverResponse](const ClangdAstNode &ast, const MessageId &) {
const auto astHandler = [this, filePath, hoverResponse](const ClangdAstNode &ast,
const MessageId &) {
const MessageId id = hoverResponse.id();
Range range;
if (const std::optional<HoverResult> result = hoverResponse.result()) {
@@ -1030,7 +1032,7 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
}
const ClangdAstPath path = getAstPath(ast, range);
if (path.isEmpty()) {
d->setHelpItemForTooltip(id, uri);
d->setHelpItemForTooltip(id, filePath);
return;
}
ClangdAstNode node = path.last();
@@ -1054,7 +1056,7 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
type = type.left(angleBracketIndex);
};
if (gatherMemberFunctionOverrideHelpItemForTooltip(id, uri, path))
if (gatherMemberFunctionOverrideHelpItemForTooltip(id, filePath, path))
return;
const bool isMemberFunction = node.role() == "expression" && node.kind() == "Member"
@@ -1062,9 +1064,8 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
const bool isFunction = node.role() == "expression" && node.kind() == "DeclRef"
&& type.contains('(');
if (isMemberFunction || isFunction) {
const auto symbolInfoHandler = [this, id, uri, type, isFunction](const QString &name,
const QString &prefix,
const MessageId &) {
const auto symbolInfoHandler = [this, id, filePath, type, isFunction]
(const QString &name, const QString &prefix, const MessageId &) {
qCDebug(clangdLog) << "handling symbol info reply";
const QString fqn = prefix + name;
@@ -1074,12 +1075,12 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
// with mainOverload = true, such information would get ignored anyway.
if (!fqn.isEmpty())
d->setHelpItemForTooltip(id,
uri,
filePath,
fqn,
HelpItem::Function,
isFunction ? type : "()");
};
requestSymbolInfo(uri.toFilePath(), range.start(), symbolInfoHandler);
requestSymbolInfo(filePath, range.start(), symbolInfoHandler);
return;
}
if ((node.role() == "expression" && node.kind() == "DeclRef")
@@ -1088,7 +1089,7 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
|| node.kind() == "Field"))) {
if (node.arcanaContains("EnumConstant")) {
d->setHelpItemForTooltip(id,
uri,
filePath,
node.detail().value_or(QString()),
HelpItem::Enum,
type);
@@ -1103,12 +1104,12 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
&& type != "double" && !type.contains(" double")
&& type != "float" && type != "bool") {
d->setHelpItemForTooltip(id,
uri,
filePath,
type,
node.qdocCategoryForDeclaration(
HelpItem::ClassOrNamespace));
} else {
d->setHelpItemForTooltip(id, uri);
d->setHelpItemForTooltip(id, filePath);
}
return;
}
@@ -1121,19 +1122,22 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
ns.prepend("::").prepend(name);
}
}
d->setHelpItemForTooltip(id, uri, ns, HelpItem::ClassOrNamespace);
d->setHelpItemForTooltip(id, filePath, ns, HelpItem::ClassOrNamespace);
return;
}
if (node.role() == "type") {
if (node.kind() == "Enum") {
d->setHelpItemForTooltip(id, uri, node.detail().value_or(QString()), HelpItem::Enum);
d->setHelpItemForTooltip(id,
filePath,
node.detail().value_or(QString()),
HelpItem::Enum);
} else if (node.kind() == "Record" || node.kind() == "TemplateSpecialization") {
stripTemplatePartOffType();
d->setHelpItemForTooltip(id, uri, type, HelpItem::ClassOrNamespace);
d->setHelpItemForTooltip(id, filePath, type, HelpItem::ClassOrNamespace);
} else if (node.kind() == "Typedef") {
d->setHelpItemForTooltip(id, uri, type, HelpItem::Typedef);
d->setHelpItemForTooltip(id, filePath, type, HelpItem::Typedef);
} else {
d->setHelpItemForTooltip(id, uri);
d->setHelpItemForTooltip(id, filePath);
}
return;
}
@@ -1141,23 +1145,23 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
const QString name = node.detail().value_or(QString());
if (!name.isEmpty())
type = name;
d->setHelpItemForTooltip(id, uri, type, HelpItem::ClassOrNamespace);
d->setHelpItemForTooltip(id, filePath, type, HelpItem::ClassOrNamespace);
}
if (node.role() == "specifier" && node.kind() == "NamespaceAlias") {
d->setHelpItemForTooltip(id,
uri,
filePath,
node.detail().value_or(QString()).chopped(2),
HelpItem::ClassOrNamespace);
return;
}
d->setHelpItemForTooltip(id, uri);
d->setHelpItemForTooltip(id, filePath);
};
d->getAndHandleAst(doc, astHandler, AstCallbackMode::SyncIfPossible);
}
bool ClangdClient::gatherMemberFunctionOverrideHelpItemForTooltip(
const LanguageServerProtocol::MessageId &token,
const DocumentUri &uri,
const Utils::FilePath &filePath,
const QList<ClangdAstNode> &path)
{
// Heuristic: If we encounter a member function re-declaration, continue under the
@@ -1196,7 +1200,7 @@ bool ClangdClient::gatherMemberFunctionOverrideHelpItemForTooltip(
if (!baseClassNode.detail())
return false;
d->setHelpItemForTooltip(token,
uri,
filePath,
*baseClassNode.detail() + "::" + *methodNode.detail(),
HelpItem::Function,
"()");
@@ -1320,7 +1324,7 @@ QTextCursor ClangdClient::Private::adjustedCursor(const QTextCursor &cursor,
}
void ClangdClient::Private::setHelpItemForTooltip(const MessageId &token,
const DocumentUri &uri,
const Utils::FilePath &filePath,
const QString &fqn,
HelpItem::Category category,
const QString &type)
@@ -1344,7 +1348,7 @@ void ClangdClient::Private::setHelpItemForTooltip(const MessageId &token,
if (category == HelpItem::Enum && !type.isEmpty())
mark = type;
const HelpItem helpItem(helpIds, uri.toFilePath(), mark, category);
const HelpItem helpItem(helpIds, filePath, mark, category);
if (isTesting)
emit q->helpItemGathered(helpItem);
else

View File

@@ -74,10 +74,9 @@ public:
void gatherHelpItemForTooltip(
const LanguageServerProtocol::HoverRequest::Response &hoverResponse,
const LanguageServerProtocol::DocumentUri &uri);
bool gatherMemberFunctionOverrideHelpItemForTooltip(
const LanguageServerProtocol::MessageId &token,
const LanguageServerProtocol::DocumentUri &uri,
const Utils::FilePath &filePath);
bool gatherMemberFunctionOverrideHelpItemForTooltip(const LanguageServerProtocol::MessageId &token,
const Utils::FilePath &uri,
const QList<ClangdAstNode> &path);
void setVirtualRanges(const Utils::FilePath &filePath,

View File

@@ -193,7 +193,7 @@ ClangdFindReferences::ClangdFindReferences(ClangdClient *client, const Link &lin
client->openExtraFile(link.targetFilePath, contents);
d->checkUnusedData->openedExtraFileForLink = true;
}
const TextDocumentIdentifier documentId(DocumentUri::fromFilePath(link.targetFilePath));
const TextDocumentIdentifier documentId(client->hostPathToServerUri(link.targetFilePath));
const Position pos(link.targetLine - 1, link.targetColumn);
ReferenceParams params(TextDocumentPositionParams(documentId, pos));
params.setContext(ReferenceParams::ReferenceContext(true));
@@ -280,7 +280,7 @@ void ClangdFindReferences::Private::handleFindUsagesResult(const QList<Location>
for (const Location &loc : locations)
fileData[loc.uri()].rangesAndLineText.push_back({loc.range(), {}});
for (auto it = fileData.begin(); it != fileData.end();) {
const Utils::FilePath filePath = it.key().toFilePath();
const Utils::FilePath filePath = client()->serverUriToHostPath(it.key());
if (!filePath.exists()) { // https://github.com/clangd/clangd/issues/935
it = fileData.erase(it);
continue;
@@ -303,19 +303,19 @@ void ClangdFindReferences::Private::handleFindUsagesResult(const QList<Location>
}
for (auto it = fileData.begin(); it != fileData.end(); ++it) {
const FilePath filePath = it.key().toFilePath();
const FilePath filePath = client()->serverUriToHostPath(it.key());
const TextDocument * const doc = client()->documentForFilePath(filePath);
const bool openExtraFile = !doc && (!checkUnusedData
|| !checkUnusedData->openedExtraFileForLink
|| checkUnusedData->link.targetFilePath != filePath);
if (openExtraFile)
client()->openExtraFile(it.key().toFilePath(), it->fileContent);
client()->openExtraFile(filePath, it->fileContent);
it->fileContent.clear();
const auto docVariant = doc ? ClangdClient::TextDocOrFile(doc)
: ClangdClient::TextDocOrFile(it.key().toFilePath());
const auto astHandler = [sentinel = QPointer(q), this, loc = it.key()](
: ClangdClient::TextDocOrFile(filePath);
const auto astHandler = [sentinel = QPointer(q), this, loc = it.key(), filePath](
const ClangdAstNode &ast, const MessageId &reqId) {
qCDebug(clangdLog) << "AST for" << loc.toFilePath();
qCDebug(clangdLog) << "AST for" << filePath;
if (!sentinel)
return;
if (!search || canceled)
@@ -324,7 +324,7 @@ void ClangdFindReferences::Private::handleFindUsagesResult(const QList<Location>
data.ast = ast;
pendingAstRequests.removeOne(reqId);
qCDebug(clangdLog) << pendingAstRequests.size() << "AST requests still pending";
addSearchResultsForFile(loc.toFilePath(), data);
addSearchResultsForFile(filePath, data);
fileData.remove(loc);
if (pendingAstRequests.isEmpty() && !canceled) {
qCDebug(clangdLog) << "retrieved all ASTs";
@@ -335,7 +335,7 @@ void ClangdFindReferences::Private::handleFindUsagesResult(const QList<Location>
docVariant, astHandler, ClangdClient::AstCallbackMode::AlwaysAsync, {});
pendingAstRequests << reqId;
if (openExtraFile)
client()->closeExtraFile(it.key().toFilePath());
client()->closeExtraFile(filePath);
}
}
@@ -370,7 +370,7 @@ void ClangdFindReferences::Private::reportAllSearchResultsAndFinish()
{
if (!checkUnusedData) {
for (auto it = fileData.begin(); it != fileData.end(); ++it)
addSearchResultsForFile(it.key().toFilePath(), it.value());
addSearchResultsForFile(client()->serverUriToHostPath(it.key()), it.value());
}
finishSearch();
}
@@ -647,7 +647,7 @@ public:
Private(ClangdFindLocalReferences *q, TextDocument *document, const QTextCursor &cursor,
const RenameCallback &callback)
: q(q), document(document), cursor(cursor), callback(callback),
uri(DocumentUri::fromFilePath(document->filePath())),
uri(client()->hostPathToServerUri(document->filePath())),
revision(document->document()->revision())
{}
@@ -749,7 +749,12 @@ void ClangdFindLocalReferences::Private::checkDefinitionAst(const ClangdAstNode
void ClangdFindLocalReferences::Private::handleReferences(const QList<Location> &references)
{
qCDebug(clangdLog) << "found" << references.size() << "local references";
const Utils::Links links = Utils::transform(references, &Location::toLink);
const auto transformLocation = [mapper = client()->hostPathMapper()](const Location &loc) {
return loc.toLink(mapper);
};
const Utils::Links links = Utils::transform(references, transformLocation);
// The callback only uses the symbol length, so we just create a dummy.
// Note that the calculation will be wrong for identifiers with

View File

@@ -72,7 +72,7 @@ public:
CppEditorWidget *editorWidget, const FilePath &filePath, const LinkHandler &callback,
bool openInSplit)
: q(q), client(client), cursor(cursor), editorWidget(editorWidget),
uri(DocumentUri::fromFilePath(filePath)), callback(callback),
uri(client->hostPathToServerUri(filePath)), callback(callback),
virtualFuncAssistProvider(q),
docRevision(editorWidget ? editorWidget->textDocument()->document()->revision() : -1),
openInSplit(openInSplit) {}
@@ -246,7 +246,7 @@ void ClangdFollowSymbol::Private::sendGotoImplementationRequest(const Link &link
if (!client->documentForFilePath(link.targetFilePath) && addOpenFile(link.targetFilePath))
client->openExtraFile(link.targetFilePath);
const Position position(link.targetLine - 1, link.targetColumn);
const TextDocumentIdentifier documentId(DocumentUri::fromFilePath(link.targetFilePath));
const TextDocumentIdentifier documentId(client->hostPathToServerUri(link.targetFilePath));
GotoImplementationRequest req(TextDocumentPositionParams(documentId, position));
req.setResponseCallback([sentinel = QPointer(q), this, reqId = req.id()]
(const GotoImplementationRequest::Response &response) {
@@ -363,12 +363,13 @@ void ClangdFollowSymbol::Private::goToTypeDefinition()
if (!sentinel)
return;
Link link;
if (const std::optional<GotoResult> &result = response.result()) {
if (const auto ploc = std::get_if<Location>(&*result)) {
link = {ploc->toLink()};
link = {ploc->toLink(client->hostPathMapper())};
} else if (const auto plloc = std::get_if<QList<Location>>(&*result)) {
if (!plloc->empty())
link = plloc->first().toLink();
link = plloc->first().toLink(client->hostPathMapper());
}
}
q->emitDone(link);
@@ -399,12 +400,15 @@ void ClangdFollowSymbol::Private::handleGotoDefinitionResult()
void ClangdFollowSymbol::Private::handleGotoImplementationResult(
const GotoImplementationRequest::Response &response)
{
auto transformLink = [mapper = client->hostPathMapper()](const Location &loc) {
return loc.toLink(mapper);
};
if (const std::optional<GotoResult> &result = response.result()) {
QList<Link> newLinks;
if (const auto ploc = std::get_if<Location>(&*result))
newLinks = {ploc->toLink()};
newLinks = {transformLink(*ploc)};
if (const auto plloc = std::get_if<QList<Location>>(&*result))
newLinks = transform(*plloc, &Location::toLink);
newLinks = transform(*plloc, transformLink);
for (const Link &link : std::as_const(newLinks)) {
if (!allLinks.contains(link)) {
allLinks << link;
@@ -465,33 +469,34 @@ void ClangdFollowSymbol::Private::handleGotoImplementationResult(
if (link == defLink)
continue;
const TextDocumentIdentifier doc(DocumentUri::fromFilePath(link.targetFilePath));
const TextDocumentIdentifier doc(client->hostPathToServerUri(link.targetFilePath));
const TextDocumentPositionParams params(doc, pos);
GotoDefinitionRequest defReq(params);
defReq.setResponseCallback([this, link, sentinel = QPointer(q), reqId = defReq.id()]
(const GotoDefinitionRequest::Response &response) {
qCDebug(clangdLog) << "handling additional go to definition reply for"
<< link.targetFilePath << link.targetLine;
if (!sentinel)
return;
Link newLink;
if (std::optional<GotoResult> _result = response.result()) {
const GotoResult result = _result.value();
if (const auto ploc = std::get_if<Location>(&result)) {
newLink = ploc->toLink();
} else if (const auto plloc = std::get_if<QList<Location>>(&result)) {
if (!plloc->isEmpty())
newLink = plloc->value(0).toLink();
defReq.setResponseCallback(
[this, link, transformLink, sentinel = QPointer(q), reqId = defReq.id()](
const GotoDefinitionRequest::Response &response) {
qCDebug(clangdLog) << "handling additional go to definition reply for"
<< link.targetFilePath << link.targetLine;
if (!sentinel)
return;
Link newLink;
if (std::optional<GotoResult> _result = response.result()) {
const GotoResult result = _result.value();
if (const auto ploc = std::get_if<Location>(&result)) {
newLink = transformLink(*ploc);
} else if (const auto plloc = std::get_if<QList<Location>>(&result)) {
if (!plloc->isEmpty())
newLink = transformLink(plloc->value(0));
}
}
}
qCDebug(clangdLog) << "def link is" << newLink.targetFilePath << newLink.targetLine;
declDefMap.insert(link, newLink);
pendingGotoDefRequests.removeOne(reqId);
if (pendingSymbolInfoRequests.isEmpty() && pendingGotoDefRequests.isEmpty()
qCDebug(clangdLog) << "def link is" << newLink.targetFilePath << newLink.targetLine;
declDefMap.insert(link, newLink);
pendingGotoDefRequests.removeOne(reqId);
if (pendingSymbolInfoRequests.isEmpty() && pendingGotoDefRequests.isEmpty()
&& defLinkNode.isValid()) {
handleDocumentInfoResults();
}
});
handleDocumentInfoResults();
}
});
pendingGotoDefRequests << defReq.id();
qCDebug(clangdLog) << "sending additional go to definition request"
<< link.targetFilePath << link.targetLine;

View File

@@ -24,11 +24,10 @@ void ClangdQuickFixFactory::match(const CppEditor::Internal::CppQuickFixInterfac
if (!client)
return;
const auto uri = DocumentUri::fromFilePath(interface.filePath());
QTextCursor cursor(interface.textDocument());
cursor.setPosition(interface.position());
cursor.select(QTextCursor::LineUnderCursor);
const QList<Diagnostic> &diagnostics = client->diagnosticsAt(uri, cursor);
const QList<Diagnostic> &diagnostics = client->diagnosticsAt(interface.filePath(), cursor);
for (const Diagnostic &diagnostic : diagnostics) {
ClangdDiagnostic clangdDiagnostic(diagnostic);
if (const auto actions = clangdDiagnostic.codeActions()) {

View File

@@ -31,7 +31,7 @@ class ClangdSwitchDeclDef::Private
public:
Private(ClangdSwitchDeclDef * q, ClangdClient *client, TextDocument *doc,
const QTextCursor &cursor, CppEditorWidget *editorWidget, const LinkHandler &callback)
: q(q), client(client), document(doc), uri(DocumentUri::fromFilePath(doc->filePath())),
: q(q), client(client), document(doc), uri(client->hostPathToServerUri(doc->filePath())),
cursor(cursor), editorWidget(editorWidget), callback(callback)
{}

View File

@@ -163,7 +163,9 @@ ClangSourceRange convertRange(const FilePath &filePath, const Range &src)
return ClangSourceRange(start, end);
}
ClangDiagnostic convertDiagnostic(const ClangdDiagnostic &src, const FilePath &filePath)
ClangDiagnostic convertDiagnostic(const ClangdDiagnostic &src,
const FilePath &filePath,
const DocumentUri::PathMapper &mapper)
{
ClangDiagnostic target;
target.location = convertRange(filePath, src.range()).start;
@@ -226,7 +228,8 @@ ClangDiagnostic convertDiagnostic(const ClangdDiagnostic &src, const FilePath &f
for (auto it = changes->cbegin(); it != changes->cend(); ++it) {
for (const TextEdit &textEdit : it.value()) {
fixItDiag.fixIts << ClangFixIt(textEdit.newText(),
convertRange(it.key().toFilePath(), textEdit.range()));
convertRange(it.key().toFilePath(mapper),
textEdit.range()));
}
}
target.children << fixItDiag;
@@ -270,7 +273,7 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath,
ClangdClient *client)
: TextEditor::TextMark(filePath, int(diagnostic.range().start().line() + 1), client->id())
, m_lspDiagnostic(diagnostic)
, m_diagnostic(convertDiagnostic(ClangdDiagnostic(diagnostic), filePath))
, m_diagnostic(convertDiagnostic(ClangdDiagnostic(diagnostic), filePath, client->hostPathMapper()))
, m_client(client)
{
setSettingsPage(CppEditor::Constants::CPP_CLANGD_SETTINGS_ID);
@@ -319,8 +322,7 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath,
bool ClangdTextMark::addToolTipContent(QLayout *target) const
{
const auto canApplyFixIt = [c = m_client, diag = m_lspDiagnostic, fp = fileName()] {
return QTC_GUARD(c) && c->reachable()
&& c->hasDiagnostic(DocumentUri::fromFilePath(fp), diag);
return QTC_GUARD(c) && c->reachable() && c->hasDiagnostic(fp, diag);
};
const QString clientName = QTC_GUARD(m_client) ? m_client->name() : "clangd [unknown]";
target->addWidget(ClangDiagnosticWidget::createWidget({m_diagnostic},