forked from qt-creator/qt-creator
LSP: Support remote LSP file paths
Change-Id: If3cf1b8d675ef091427dbcd703c7d14b384a1b3a Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -387,7 +387,7 @@ MessageId requestAst(Client *client, const FilePath &filePath, const Range range
|
||||
explicit AstRequest(const AstParams ¶ms) : 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();
|
||||
|
||||
@@ -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 ¶ms)
|
||||
{
|
||||
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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
|
||||
|
||||
@@ -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},
|
||||
|
||||
Reference in New Issue
Block a user